/*************************************************************************
C *** This program is proprietary to ELSAG BAILEY and may only be used ***
C *** as authorized  in a license agreement controlling such use.      ***
C*************************************************************************
C
C  10  Name
C
C  20  Purpose
C
C  30  Description
C       Author        Date         Version    Reason
C       ---------    -----------   -------   ---------------------------------
C
C  40  Calling Sequence/Execution Criteria
C
C  50  Common Usage
C  60  Input/Output
C  70  Method
C
C***********************************************************************/

#define ALONE_TWN_EXEC_N_MOV
#include "Twn_Exec_N_Mov.h"
	

BOOL WINAPI DllMain(HINSTANCE hinstDLL,  // handle to DLL module
					DWORD fdwReason,     // reason for calling function
					LPVOID lpReserved )  // reserved
					{
	LONG	res;
	LPDWORD	type;
	LPBYTE	data;
	LPDWORD size;
	HKEY	hKey;
	TCHAR	szProductType[ENM_NAME_L];
    DWORD	dwBufLen = ENM_NAME_L;
	DWORD	active;
    
	size = 0;
	data = 0;
	type = 0;
	
	switch(fdwReason){ 
		case DLL_PROCESS_ATTACH:
			res = RegOpenKeyEx(	HKEY_LOCAL_MACHINE, 
							TEXT("SOFTWARE\\ABB\\Power Generation Portal\\Tianwan\\Twn_Exec_N_Mov"),
							0,
							KEY_QUERY_VALUE,
							&hKey);
			if(res != ERROR_SUCCESS)
				return(FALSE);	
			
			res = RegQueryValueEx(	hKey,
									TEXT("LogPath"),
									NULL,
									NULL,
									(LPBYTE)szProductType,
									&dwBufLen);
			if(res == ERROR_SUCCESS)
				_stprintf_s(ENM_LogPath, (TCHAR*)szProductType);
			
			active = 0;
			dwBufLen = sizeof(active);
			res = RegQueryValueEx(	hKey,
									TEXT("LogActive"),
									NULL,
									NULL,
									(LPBYTE)&active,
									&dwBufLen);
			if(res == ERROR_SUCCESS){
				if((DWORD)active == 0)
					ENM_LogActive = false;
				else
					ENM_LogActive = true;
			}
			
			active = 0;
			dwBufLen = sizeof(active);
			res = RegQueryValueEx(	hKey,
									TEXT("MsgBoxActive"),
									NULL,
									NULL,
									(LPBYTE)&active,
									&dwBufLen);
			if(res == ERROR_SUCCESS){
				if((DWORD)active == 0)
					ENM_MsgBoxActive = false;
				else
					ENM_MsgBoxActive = true;
			}

			break;
		default:
			break;
	}
    return TRUE;  // Successful DLL_PROCESS_ATTACH.
}

/*
DWORD WINAPI SippFunction(LPVOID lpParam){
	RETSTAT		retSt;
	HWND		hWnd = NULL;

	//hWnd = (HWND)(*lpParam);
	retSt = TwnExeSipp(hWnd);
	if(retSt != RT_NORMAL)
		return(-1);
	return(0);
}
*/

/*********************************************************************************************
**********************************************************************************************
**
** Function:		Exe_N_Mov
**
** Description:		Execute the next micro-op defined in the dynamic properties structure.
**
** Input			hWnd			- Handle of the window that displays results (Movemets). 
**					hWnd_tc			- Handle of the window that displays results (Tech. Cyc.). 
** Output			index			- Index of last executed operation.
**
** Return:			RETCOND			- R_NORMAL	-	Operation successful.
**									- R_XXXXXX	-	Otherwise.
** 
**********************************************************************************************
*********************************************************************************************/
RETSTAT Exe_N_Mov (HWND hWnd, HWND hWnd_tc, int *index){
	RETCOND			stat;
	RETSTAT			retstat;
	TAGIDX			tagIdx;
	TAGVALEX		tagVal;
	FILEIDX			fileMice;
	FILEIDX			filePhas;
	GENIDX			PhasObjtIdx;
	GENIDX			PhasObjIdx;
//	GENIDX			cellType;
	GENIDX			zoneIdx;
	GENIDX			zoneIOIdx;
	GENIDX			tc1GIdx;
	GENIDX			tc1HIdx;
	GENIDX			tc1H1Idx;
	GENIDX			phasTcIdx;
//	OBJTCELL		cellSituation;
//	OBJTMM			mastSituation;
	OBJTNAME		PhasObjtName;
	OBJNAME			PhasObjName;
//	DWORD			dwThreadId;
	DWORD			dwThrdParam = 1; 
//  HANDLE			hThread; 
	micro_cmd_exe	micro_exe;
//	micro_cmd_exe	prevMice;
	t_falv			falv;
	t_dmp			dmp;
	t_camp			camp;
	t_rpmb			rpmb;
	TCHAR			mbStr[128];
	TCHAR			objtDescr[MAX_OBJ_DESCR];
	int				next_move_a;
	int				i;
//	int				j;
	int				current_mode;
	int				current_phase;
	int				next_phase;
	int				genTypeCode;
	int				risp;
	int				sippReq;
	int				stopFlag;
	int				tcObj;
	int				vx;
	int				vy;
	int				chkVx;
	int				chkVy;
	int				Rot_Flag;
	int				nextMark;
	TV_angle		TV_range;
	short int		svx, svy, dvx, dvy;
//	float			weight, objWeight, clgrWeight;
//	float			mastAngle;
//	float			mmTDPos;
	float			px;
	float			py;
	bool			sendMsg;
	bool			sendMsg_tc;
//	bool			clusOnMast;
//	bool			cellUpdated;

	fileMice.num = F_MICE;
	filePhas.num = F_PHAS;

	sippReq = 0;

	if(hWnd == NULL)
		sendMsg = false;
	else
		sendMsg = true;

	if(hWnd_tc == NULL)
		sendMsg_tc = false;
	else
		sendMsg_tc = true;


	//Prelevo la fase corrente.//
	retstat = GetDynCurrentPhase(&current_phase);
	if(retstat != RT_NORMAL){
		_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve dynamic current phase."));
		ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(102));
		return(RT_FAILED);
	}
	if(current_phase == 0){
		_stprintf_s(ENM_LogMsg, _T("Error: dynamic current phase = 0."));
		ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(103));
		return (RT_INVPHAS);
	}
	
	GetTechCycIdx(_T("1G"), &tc1GIdx);
	GetTechCycIdx(_T("1H"), &tc1HIdx);
	GetTechCycIdx(_T("1H1"), &tc1H1Idx);
	GetPhasTecCycIdx(current_phase, &phasTcIdx);

	retstat = SetSSTREntryEx(SSTR_TC_REC, NULL);
	retstat = SetSSTREntryEx(SSTR_COORD_REC, NULL);
	retstat = SetSSTREntryEx(SSTR_OBJ_REC, NULL);

	retstat = GetZoneIdx(ZONE_IO, &zoneIOIdx);

	retstat = GetPhaseMicroOpNum(current_phase, &next_move_a);
	//retstat = GetDynNextMove_a ( &next_move_a );
	if(retstat != RT_NORMAL){
		_stprintf_s(ENM_LogMsg, _T("Error: cannot read next automatic operation from DAFS file F.DYNP."));
		ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(100));
		return(retstat);
	}
	if ( next_move_a > N_MAX_MICENR )
		next_move_a = N_MAX_MICENR;
	
	for (i = 1; i <= next_move_a; i++){
		stat = FileRead ( &fileMice, i, 1, &micro_exe, sizeof(micro_exe) );
		if(stat != R_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot read from DAFS file F.MICE."));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(101));
			if(sendMsg)
				SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
			return(RT_FAILED);
		}
		if ( stat != R_NORMAL ){
			if(sendMsg)
				SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
			SetPhaseStatus(current_phase, PHAS_FAILED);
			return (RT_FAILED);
		}
		if (micro_exe.exe == MICE_SUCCESS) //eseguita con successo, quindi ritorno all'inizio del for.//
			continue;
		
		if (micro_exe.exe == MICE_INPROGR){ //operazione in esecuzione, esco dalla funzione.//
			if(sendMsg)
				SendMessage(hWnd, WM_OP_INPROG, NULL, NULL);
			return (RT_INVSEQ);
		}
	
		SetPhaseSourceDestTags(current_phase);

		if(micro_exe.index != 1)
			Sleep(SLEEP_BETWEEN_OP);
		else
			ResetObjectMoved();
		
		//Prelevo il modo corrente.//
		retstat = GetDynCurrentMode (&current_mode);
		if(retstat != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve dynamic currnet operating mode."));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(104));
			SetMiceStatus(micro_exe.index, MICE_BREAK);
			if(sendMsg)
				SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
			return (retstat);
		}
		if ((current_mode != M_AUTOMATIC) && (current_mode != M_SEMIAUTO)){
			_stprintf_s(ENM_LogMsg, _T("Error: invalid operating mode."));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(105));
			SetMiceStatus(micro_exe.index, MICE_BREAK);
			if(sendMsg)
				SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
			return (RT_ILLMODE);
		}

		retstat = SetDynCurrentOper((int)micro_exe.movet);
		if (retstat != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot set the dynamic current operation."));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(106));
			SetMiceStatus(micro_exe.index, MICE_BREAK);
			if(sendMsg)
				SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
			return (retstat);
		}
		
		SetStationTCFlag();

		if((!_tcscmp(micro_exe.cmovet, MICRO_MOVE_FAGR_MM))   ||	
		   (!_tcscmp(micro_exe.cmovet, MICRO_MOVE_CLGR_MM))   ||	
		   (!_tcscmp(micro_exe.cmovet, MICRO_MOVE_FAGRL_MM))){
			retstat = GetMastPosInfi(micro_exe.mast, &px, &py, &zoneIdx);
			if(retstat != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve current mast position."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(106));
				SetMiceStatus(micro_exe.index, MICE_FAILED);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_FAILED, micro_exe.index, ERR_CODE_FAIL);
				return(retstat);
			}
			vx = 0;
			vy = 0;
			retstat = GetZonePhisVirtCoord(px, py, &vx, &vy); 
			if(retstat != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve current mast virtual position."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(106));
				SetMiceStatus(micro_exe.index, MICE_FAILED);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_FAILED, micro_exe.index, ERR_CODE_FAIL);
				return(retstat);
			}

			if((micro_exe.Virt_X != vx) || (micro_exe.Virt_Y != vy)){
				_stprintf_s(ENM_LogMsg, _T("Error: FHM is not in the forseen position to execute this operation."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(106));
				SetMiceStatus(micro_exe.index, MICE_FAILED);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_FAILED, micro_exe.index, ERR_CODE_WR_COORD);
				return (retstat);
			}
		}else if((!_tcscmp(micro_exe.cmovet, MICRO_MOVEX))			||	
				 (!_tcscmp(micro_exe.cmovet, MICRO_MOVEY))			||
				 (!_tcscmp(micro_exe.cmovet, MICRO_MOVEXY))			||
				 (!_tcscmp(micro_exe.cmovet, MICRO_ROT_TV))){
			
			if((micro_exe.mast == DMP_MAST) && (micro_exe.index != 0)){
				_stprintf_s(mbStr, _T("Please confirm start of Bridge and Trolley movement."));
				risp = MessageBox(hWnd, mbStr, _T("Mounting place Inspection"), MB_YESNO | MB_ICONINFORMATION);
				if(risp == IDNO){
					_stprintf_s(ENM_LogMsg, _T("Error: Operator didn't confirmed start for bridge/trolley movement in Inspection cycle."));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(106));
					SetMiceStatus(micro_exe.index, MICE_BREAK);
					if(sendMsg)
						SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
					return (RT_FAILED);
				}
			}
			retstat = GetMastPosInfi(micro_exe.mast, &px, &py, &zoneIdx);
			if(retstat != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve Main mast mast position."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(106));
				SetMiceStatus(micro_exe.index, MICE_BREAK);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_FAILED, micro_exe.index, ERR_CODE_FAIL);
				return(retstat);
			}

			if((micro_exe.mast == MAIN_MAST) && (micro_exe.index == 1)){
				stat = GetTagIdx(TWN_TV_MOUNT, &tagIdx);
				if(stat != R_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve TWN_TV_MOUNT tag Idx."));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(106));
					SetMiceStatus(micro_exe.index, MICE_BREAK);
					if(sendMsg)
						SendMessage(hWnd, WM_OP_FAILED, micro_exe.index, ERR_CODE_FAIL);
					return(RT_FAILED);
				}

				stat = TagRead(&tagIdx, &tagVal);
				if(stat != R_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot read TWN_TV_MOUNT tag value."));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(106));
					SetMiceStatus(micro_exe.index, MICE_BREAK);
					if(sendMsg)
						SendMessage(hWnd, WM_OP_FAILED, micro_exe.index, ERR_CODE_FAIL);
					return(RT_FAILED);
				}

				if(GtBit((unsigned short)(tagVal.value.val_di), 15) == 1){
					stat = GetTagIdx(TWN_TV_ROT_POS, &tagIdx);
					if(stat != R_NORMAL){
						_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve TWN_TV_ROT_POS tag Idx."));
						ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(106));
						SetMiceStatus(micro_exe.index, MICE_BREAK);
						if(sendMsg)
							SendMessage(hWnd, WM_OP_FAILED, micro_exe.index, ERR_CODE_FAIL);
						return(RT_FAILED);
					}

					stat = TagRead(&tagIdx, &tagVal);
					if(stat != R_NORMAL){
						_stprintf_s(ENM_LogMsg, _T("Error: cannot read TWN_TV_ROT_POS tag value."));
						ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(106));
						SetMiceStatus(micro_exe.index, MICE_BREAK);
						if(sendMsg)
							SendMessage(hWnd, WM_OP_FAILED, micro_exe.index, ERR_CODE_FAIL);
						return(RT_FAILED);
					}
				
					if(IsCorrPosition(px, py) == RT_NORMAL){
						if(!(((tagVal.value.val_float >= (float)(0.0 - TOLL_MM)) && (tagVal.value.val_float <= (float)(0.0 + TOLL_MM))) ||
							((tagVal.value.val_float >= (float)(180.0 - TOLL_MM)) && (tagVal.value.val_float <= (float)(180.0 + TOLL_MM))))){
							_stprintf_s(ENM_LogMsg, _T("Error: TV Angle is illegal for the current postion. Nearest cell is (%d,%d)."), chkVx, chkVy);
							ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(106));
							SetMiceStatus(micro_exe.index, MICE_BREAK);
							if(sendMsg)
								SendMessage(hWnd, WM_OP_FAILED, micro_exe.index, ERR_CODE_TV_WRONG);
							return(retstat);
						}
					}
					else{
						retstat = GetZoneNearCell(px, py, &chkVx, &chkVy, &Rot_Flag, &TV_range, false);
						if(retstat != RT_NORMAL){
							_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve nearest cell."));
							ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(106));
							SetMiceStatus(micro_exe.index, MICE_BREAK);
							if(sendMsg)
								SendMessage(hWnd, WM_OP_FAILED, micro_exe.index, ERR_CODE_FAIL);
							return(retstat);
						}

						retstat = CheckAngleInRange(TV_range, tagVal.value.val_float);
						if(retstat == RT_FAILED){
							_stprintf_s(ENM_LogMsg, _T("Error: CheckAngleInRange failed."));
							ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(106));
							SetMiceStatus(micro_exe.index, MICE_BREAK);
							if(sendMsg)
								SendMessage(hWnd, WM_OP_FAILED, micro_exe.index, ERR_CODE_FAIL);
							return(retstat);
						}
						else if(retstat == RT_NOROTALL){
							_stprintf_s(ENM_LogMsg, _T("Error: TV Angle is illegal for the current postion. Nearest cell is (%d,%d)."), chkVx, chkVy);
							ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(106));
							SetMiceStatus(micro_exe.index, MICE_BREAK);
							if(sendMsg)
								SendMessage(hWnd, WM_OP_FAILED, micro_exe.index, ERR_CODE_TV_WRONG);
							return(retstat);
						}
					}
				}
			}

			if((px < (float)(micro_exe.startPX - (float)(TOLL_AUTO_CHECK))) ||
			   (px > (float)(micro_exe.startPX + (float)(TOLL_AUTO_CHECK))) ||
			   (py < (float)(micro_exe.startPY - (float)(TOLL_AUTO_CHECK))) ||
			   (py > (float)(micro_exe.startPY + (float)(TOLL_AUTO_CHECK)))){
				_stprintf_s(ENM_LogMsg, _T("Error: FHM is not in the planned position to execute this operation."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(106));
				SetMiceStatus(micro_exe.index, MICE_FAILED);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_FAILED, micro_exe.index, ERR_CODE_WR_COORD);
				return (retstat);
			}
		}

		SetPhaseStatus(current_phase, PHAS_INEXECUTION);
		SetMiceStatus(micro_exe.index, MICE_INPROGR);
		if(sendMsg)
			SendMessage(hWnd, WM_OP_STARTED, micro_exe.index, NULL);

		retstat = SetSSTREntryEx(SSTR_MECH_REC, &micro_exe);
		retstat = SetSSTREntryEx(SSTR_TCSEQ_REC, &micro_exe);

	
		//Prelevo i dati necessari alla gestione dei cambiamenti nelle celle.//
		retstat = GetPhaseSourceVirtCoo(micro_exe.phase, &svx, &svy);
		if(retstat != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve phase source virtual coordinates."));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
			SetMiceStatus(micro_exe.index, MICE_BREAK);
			if(sendMsg)
				SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
			return (RT_INVSOUR);
		}
		retstat = GetPhaseDestVirtCoo(micro_exe.phase, &dvx, &dvy);
		if(retstat != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve phase dest. virtual coordinates."));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
			SetMiceStatus(micro_exe.index, MICE_BREAK);
			if(sendMsg)
				SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
			return (RT_INVDEST);
		}
		
		/*
		if(micro_exe.index == 1){
			ZeroMemory(&cellSituation, sizeof(OBJTCELL));
			SetMimicCellSituation(MAIN_MAST, cellSituation);
			SetMimicCellSituation(FALC_MAST, cellSituation);
		}
		if((micro_exe.Virt_X != 0) && (micro_exe.Virt_Y != 0) && (micro_exe.mast != TV_MAST)){
			retstat = GetCellSituation(micro_exe.Virt_X, micro_exe.Virt_Y, &cellSituation);
			if(retstat != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve cell situation."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
				SetMiceStatus(micro_exe.index, MICE_BREAK);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
				return (RT_INVSOUR);
			}
			//Scrivo la nuova situazione della cella sul file dei sinottici//
			retstat = SetMimicCellSituation(micro_exe.mast, cellSituation);
			if(retstat != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot set mimics file cell situation."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
				SetMiceStatus(micro_exe.index, MICE_BREAK);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
				return (RT_INVSOUR);
			}
		}

		//Scrivo la situazione del mast in uso sul file dei sinottici//
		if(micro_exe.mast == MAIN_MAST){
			retstat = SetMimicMastSituation(micro_exe.mast);
			if(retstat != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot set mimics file mast situation."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
				SetMiceStatus(micro_exe.index, MICE_BREAK);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
				return (RT_FAILED);
			}
		}
		
		//Prelevo la situazione del mast in uso//
		if(micro_exe.mast == MAIN_MAST){
			retstat = GetMastSituation(&mastSituation);
			if(retstat != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve mast situation."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
				SetMiceStatus(micro_exe.index, MICE_BREAK);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
				return (RT_INVMAST);
			}

			if(mastSituation.obj[OBJT_N_CLUS]!= 0)
				clusOnMast = true;
			else
				clusOnMast = false;
		}
		
		  */
		GetTcObjFlag(phasTcIdx, &tcObj);
		if((phasTcIdx != tc1GIdx) && (phasTcIdx != tc1HIdx) && (phasTcIdx != tc1H1Idx)&& (tcObj)){
			retstat = GetPhaseObjtName(micro_exe.phase, PhasObjtName);
			if(retstat != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve phase object type name."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
				SetMiceStatus(micro_exe.index, MICE_BREAK);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
				return (RT_INVOBJ);
			}
			
			retstat = GetObjtIdx(PhasObjtName, &PhasObjtIdx);
			if(retstat != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve phase object type Idx."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
				SetMiceStatus(micro_exe.index, MICE_BREAK);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
				return (RT_INVOBJT);
			}

			retstat = GetObjtGenericTypeCode(PhasObjtIdx, &genTypeCode);
			if(retstat != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve generic type code."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
				SetMiceStatus(micro_exe.index, MICE_BREAK);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
				return (RT_INVOBJT);
			}
		
			if(genTypeCode < N_MAX_NAMED_OBJ){
				retstat = GetPhaseObjectName(micro_exe.phase, PhasObjName);
				if(retstat != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve phase object name."));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
					SetMiceStatus(micro_exe.index, MICE_BREAK);
					if(sendMsg)
						SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
					return (RT_INVOBJ);
				}
					
				retstat = GetObjIdx(PhasObjName, &PhasObjIdx);
				if(retstat != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve phase object Idx."));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
					SetMiceStatus(micro_exe.index, MICE_BREAK);
					if(sendMsg)
						SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
					return (RT_INVOBJT);
				}
			}
			else{
				_stprintf_s(PhasObjName, _T(""));
				PhasObjIdx = 0;
			}
		}
		
		//Gestione del marking inspection//
		if(!_tcscmp(micro_exe.cmovet, MICRO_TV_INSP)){
			stat = GetNextMarkingOpNum(micro_exe.index, &nextMark);
			if((stat != R_NORMAL) || (nextMark == 0)){ 
				GetObjtDescrFromName(PhasObjtName, objtDescr);
				if((micro_exe.Virt_X == dvx) && (micro_exe.Virt_Y == dvy))
					_stprintf_s(mbStr, _T("Please confirm presence of object %s, type %s on main mast."), PhasObjName, objtDescr, svx, svy);
				else
					_stprintf_s(mbStr, _T("Please confirm presence of object %s, type %s, \nin cell (%d,%d)."), PhasObjName, objtDescr, svx, svy);
				if(genTypeCode == OBJT_N_FA)
					risp = MessageBox(hWnd, mbStr, _T("FA Marking Inspection"), MB_YESNO | MB_ICONINFORMATION);
				else if(genTypeCode == OBJT_N_CLUS)
					risp = MessageBox(hWnd, mbStr, _T("Cluster Marking Inspection"), MB_YESNO | MB_ICONINFORMATION);
				if(risp == IDYES)
					goto PROCEED;
				else{
					MessageBox(hWnd, _T("Object marking inspection not confirmed.\nTechnological cycle will be interrupted."), _T("Marking inspection failed"), MB_OK | MB_ICONERROR);
					SetMiceStatus(micro_exe.index, MICE_BREAK);
					if(sendMsg)
						SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
					return(RT_FAILED);
				}
			}
			else{
				GetObjtDescrFromName(PhasObjtName, objtDescr);
				if((micro_exe.Virt_X == dvx) && (micro_exe.Virt_Y == dvy))
					_stprintf_s(mbStr, _T("Please confirm presence of object %s, type %s on main mast. \nPress cancel to perform marking at destination."), PhasObjName, objtDescr, svx, svy);
				else
					_stprintf_s(mbStr, _T("Please confirm presence of object %s, type %s, \nin cell (%d,%d). \nPress cancel to perform marking at destination."), PhasObjName, objtDescr, svx, svy);
				if(genTypeCode == OBJT_N_FA)
					risp = MessageBox(hWnd, mbStr, _T("FA Marking Inspection"), MB_YESNOCANCEL | MB_ICONINFORMATION);
				else if(genTypeCode == OBJT_N_CLUS)
					risp = MessageBox(hWnd, mbStr, _T("Cluster Marking Inspection"), MB_YESNOCANCEL | MB_ICONINFORMATION);
				if(risp == IDYES){
					stat = EraseNextMarking(micro_exe.index, nextMark);
					if(stat != R_NORMAL){
						MessageBox(hWnd, _T("system generated errors in sequence removing marking operation at destination."), _T("Marking inspection failed"), MB_OK | MB_ICONERROR);
						SetMiceStatus(micro_exe.index, MICE_FAILED);
						if(sendMsg)
							SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
						return(RT_FAILED);
					}
					else{
						SetPhasMarkReq(current_phase, 0);
						if(sendMsg)
							SendMessage(hWnd, WM_UPDATE_SEQ, NULL, NULL);
						next_move_a = next_move_a - 2;
					}
					goto PROCEED;
				}
				else if(risp == IDCANCEL){
					MessageBox(hWnd, _T("Object marking inspection skipped.\nMArking operation will be performed at destination cell."), _T("Marking inspection skipped"), MB_OK | MB_ICONWARNING);
					goto PROCEED;
				}
				else{
					MessageBox(hWnd, _T("Object marking inspection not confirmed.\nTechnological cycle will be interrupted."), _T("Marking inspection failed"), MB_OK | MB_ICONERROR);
					SetMiceStatus(micro_exe.index, MICE_BREAK);
					if(sendMsg)
						SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
					return(RT_FAILED);
				}
			
			
			
			}
		}

		//Gestione dell'inspection of FA mounting places//
		if(!_tcscmp(micro_exe.cmovet, MICRO_DMP_OP)){
			_stprintf_s(mbStr, _T("Click YES button when inspection has been completed.\nClick NO to interrupt technological cycle."));
			risp = MessageBox(hWnd, mbStr, _T("Inspection of mounting places"), MB_YESNO | MB_ICONINFORMATION);
			if(risp == IDYES)
				goto PROCEED;
			else{
				SetMiceStatus(micro_exe.index, MICE_BREAK);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_BREAK, micro_exe.index, NULL);
				return(RT_FAILED);
			}
		}

		//Imposto la tag che indica ai sinottici il mast utilizzato.//
		stat = GetTagIdx(TWN_U_ROD_USED, &tagIdx);
		if(stat != R_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot find idx for tag U_ROD_USED"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(60));
			SetMiceStatus(micro_exe.index, MICE_BREAK);
			if(sendMsg)
				SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
			return(RT_FAILED);
		}
		tagVal.value.val_float = (float)(micro_exe.mast + 1);
		stat = TagWrite ( &tagIdx, &tagVal, TAG_CMD );
		if(stat != R_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag U_ROD_USED"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(61));
			SetMiceStatus(micro_exe.index, MICE_BREAK);
			if(sendMsg)
				SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
			return(RT_FAILED);
		}

		/*
		//Imposto i tipi di oggetti presenti sul mast.//
		if(micro_exe.mast == MAIN_MAST){
			stat = SetObjectOnMast(micro_exe.mast, mastSituation);
			if(stat != R_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tags the objects on mast."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(61));
				SetMiceStatus(micro_exe.index, MICE_BREAK);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
				return(RT_FAILED);
			}

			//Imposto i tipi di oggetti spostati.//
			retstat = SetToMoveTags(micro_exe.index);
			if(retstat != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: unable to set objects actually moved."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(107));
				SetMiceStatus(micro_exe.index, MICE_BREAK);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
				return (RT_FAILED);
			}
		}

		//Controllo il peso sul mast.//
		if(micro_exe.mast == MAIN_MAST){
			clgrWeight = 0.0;
			if((mastSituation.obj[OBJT_N_CLUS] != 0) && (mastSituation.obj[OBJT_N_CLUS_CAS] != 0)){
				retstat = GetObjWeight(mastSituation.o_id[OBJT_N_CLUS], &objWeight);
				if(retstat != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: unable to retrieve object weight."));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
					SetMiceStatus(micro_exe.index, MICE_BREAK);
					if(sendMsg)
						SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
					return (RT_INVOBJ);
				}
				clgrWeight = objWeight;
			}
			weight = 0.0;
			objWeight = 0.0;
			for(j = 0; j < N_MAX_NONAM_OBJ; j++){
				if(mastSituation.obj[j] != 0){
					if(j < N_MAX_NAMED_OBJ){
						if(j == OBJT_N_CLUS){ 
							if((mastSituation.obj[OBJT_N_CLUS_CAS] == 0) && (j != OBJT_N_CLUS)){
								retstat = GetObjWeight(mastSituation.o_id[j], &objWeight);
								if(retstat != RT_NORMAL){
									_stprintf_s(ENM_LogMsg, _T("Error: unable to retrieve object weight."));
									ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
									SetMiceStatus(micro_exe.index, MICE_BREAK);
									if(sendMsg)
										SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
									return (RT_INVOBJ);
								}
							}
						}
						else{
							retstat = GetObjWeight(mastSituation.o_id[j], &objWeight);
							if(retstat != RT_NORMAL){
								_stprintf_s(ENM_LogMsg, _T("Error: unable to retrieve object weight."));
								ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
								SetMiceStatus(micro_exe.index, MICE_BREAK);
								if(sendMsg)
									SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
								return (RT_INVOBJ);
							}
						}
					}
					else{
						retstat = GetObjtWeight(mastSituation.obj[j], &objWeight);
						if(retstat != RT_NORMAL){
							_stprintf_s(ENM_LogMsg, _T("Error: unable to retrieve object type weight."));
							ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
							SetMiceStatus(micro_exe.index, MICE_BREAK);
							if(sendMsg)
								SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
							return (RT_INVOBJT);
						}
					}
					weight = weight + objWeight;
				}
			}

			switch(micro_exe.mast){
			case MAIN_MAST:
				//Imposto il peso per l'FA gripper del MM.//
				retstat = VotedTagWrite(TWN_MM_EXP_WEIGHT, 0, weight, FLT_VALUE);
				if(retstat != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag MR_EXP"));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(61));
					SetMiceStatus(micro_exe.index, MICE_BREAK);
					if(sendMsg)
						SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
					return(RT_FAILED);
				}
				//Imposto il peso per il cluster gripper del MM.//
				retstat = VotedTagWrite(TWN_MM_CL_EXP_WEIGHT, 0, clgrWeight, FLT_VALUE);
				if(retstat != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag MR_CL_EXP"));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(61));
					SetMiceStatus(micro_exe.index, MICE_BREAK);
					if(sendMsg)
						SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
					return(RT_FAILED);
				}
				break;
			default:
				break;
			}
		}

		//Imposto la tag che indica ai sinottici il tipo di cella utilizzata.//
		stat = GetTagIdx(TWN_U_CELL_TYPE, &tagIdx);
		if(stat != R_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot find idx for tag U_CELL_TYPE"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(60));
			SetMiceStatus(micro_exe.index, MICE_BREAK);
			if(sendMsg)
				SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
			return(RT_FAILED);
		}
		stat = TagRead(&tagIdx, &tagVal);
		if(stat != R_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot read tag U_CELL_TYPE"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(60));
			SetMiceStatus(micro_exe.index, MICE_BREAK);
			if(sendMsg)
				SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
			return(RT_FAILED);
		}
		if((micro_exe.Virt_X != 0) && (micro_exe.Virt_Y != 0)){
			retstat = GetCellType(micro_exe.Virt_X, micro_exe.Virt_Y, &cellType);
			if(retstat != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve cell type."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(61));
				SetMiceStatus(micro_exe.index, MICE_BREAK);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
				return(RT_FAILED);
			}
		
			retstat = GetZoneIdxVirtCoo(micro_exe.Virt_X, micro_exe.Virt_Y, &zoneIdx);
			if(zoneIdx == zoneIOIdx)
				tagVal.value.val_float = CELL_TYPE_FA_Z1;
			else{
				switch(cellType){
				case CELL_FA:
						tagVal.value.val_float = CELL_TYPE_FA;
					break;
				case CELL_HECA:
					tagVal.value.val_float = CELL_TYPE_HECA;
					break;
				case CELL_COVER_PLUG:
					tagVal.value.val_float = CELL_TYPE_CLUS_VIEW;
					break;
				case CELL_COVER_PLUG_EX:
					tagVal.value.val_float = CELL_TYPE_COVPL_CLJ;
					break;
				case CELL_FFDS_CASK:
					tagVal.value.val_float = CELL_TYPE_FFDS;
					break;
				}
			}
			stat = TagWrite(&tagIdx, &tagVal, TAGWRITE_STD);
			if(stat != R_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag U_CELL_TYPE"));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(61));
				SetMiceStatus(micro_exe.index, MICE_BREAK);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
				return(RT_FAILED);
			}	
		}

	*/

		stat = ExeMFPOutput(&micro_exe, &rpmb, sippReq);
		if (stat != R_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: ExeMFPOutput exited with RETCOND = %d."), stat);
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(107));
			if(sendMsg){
				micro_exe.exe = MICE_FAILED;
				SetMiceStatus(micro_exe.index, MICE_FAILED);
				stat = SetMicroOpResults(&micro_exe);
				if(stat == R_INVTAG)
					SendMessage(hWnd, WM_OP_FAILED, micro_exe.index, ERR_CODE_SP);
				else
					SendMessage(hWnd, WM_OP_FAILED, micro_exe.index, ERR_CODE_FAIL);
			}
			else{
				micro_exe.exe = MICE_FAILED;
				SetMiceStatus(micro_exe.index, MICE_FAILED);
				stat = SetMicroOpResults(&micro_exe);
			}
			return (RT_FAILED);
		}

		//Faccio eseguire la mirooperazione con la funzione apposita che manda i segnali all'INFI.//
		
		stat = ExeMFPInput(&micro_exe, &rpmb);
		if ( stat != R_NORMAL ){
			if(stat == R_FAILED){
				if(sendMsg){
					micro_exe.exe = MICE_FAILED;
					SetMiceStatus(micro_exe.index, MICE_FAILED);
					stat = SetMicroOpResults(&micro_exe);
					_stprintf_s(ENM_LogMsg, _T("Error: ExeMFPInput failed."));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(109));
					SendMessage(hWnd, WM_OP_FAILED, micro_exe.index, ERR_CODE_FAIL);
				}
				if(!_tcscmp(micro_exe.cmovet, MICRO_MOVE_CLGR_MM)){
					retstat = ManageClusEngage(micro_exe, hWnd);
					if(retstat != RT_NORMAL){
						_stprintf_s(ENM_LogMsg, _T("Cluster position management failed."));
						ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(109));
					}else{
						_stprintf_s(ENM_LogMsg, _T("Cluster position management completed."));
						ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(109));
						if(sendMsg)
							SendMessage(hWnd, WM_OP_REFRESH, micro_exe.index - 1, 0);
					}
				}
			}
			else if(stat == R_ABORTED){
				if((!_tcscmp(micro_exe.cmovet, MICRO_MOVEX))			||	
				   (!_tcscmp(micro_exe.cmovet, MICRO_MOVEY))			||
				   (!_tcscmp(micro_exe.cmovet, MICRO_MOVEXY))		||
				   (!_tcscmp(micro_exe.cmovet, MICRO_ROT_TV))){
					
					GENIDX mastType;
					retstat = GetMastMounted(&mastType);
					if(retstat != RT_NORMAL)
						return (RT_FAILED);

					retstat = GetMastPosInfi(mastType, &px, &py, &zoneIdx);
					if(retstat != RT_NORMAL)
						return (RT_FAILED);

					retstat = SetMiceStartPos(micro_exe.index, px, py);
					if(retstat != RT_NORMAL)
						return (RT_FAILED);
				}
				_stprintf_s(ENM_LogMsg, _T("Error: ExeMFPInput aborted."));
				ENM_LogFileWrite(_T("WRN"), ENM_LogMsg, ENM_ERR_CODE(109));

				micro_exe.exe = MICE_STOPPED;

				SetMiceStatus(micro_exe.index, MICE_STOPPED);
				stat = SetMicroOpResults(&micro_exe);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_STOPPED, micro_exe.index, NULL);
			}
			return (RT_FAILED);
		}
		
		stat = SetMicroOpResults(&micro_exe);
		if(stat != R_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error saving micro operation results."));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(109));
			micro_exe.exe = MICE_FAILED;
			SetMiceStatus(micro_exe.index, MICE_FAILED);
			if(sendMsg)
				SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
			return (RT_FAILED);
		}

		/*
		if((micro_exe.Virt_X != 0) && (micro_exe.Virt_Y != 0)){
			retstat = GetCellType(micro_exe.Virt_X, micro_exe.Virt_Y, &cellType);
			if(retstat != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve cell type."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(61));
				SetMiceStatus(micro_exe.index, MICE_BREAK);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
				return(RT_FAILED);
			}
		}
		cellUpdated = false;
		retstat = MastInTouchdown(MAIN_MAST, &mmTDPos);
		if(retstat != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot check main mast touchdown position."));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(61));
			SetMiceStatus(micro_exe.index, MICE_FAILED);
			if(sendMsg)
				SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
			return(RT_FAILED);
		}
		//Gestione delle variazioni sul database dovute alle operazioni.//
		if(!_tcscmp(micro_exe.cmovet, MICRO_MOVEX)        ||
		   !_tcscmp(micro_exe.cmovet, MICRO_MOVEY)        ||
		   !_tcscmp(micro_exe.cmovet, MICRO_MOVEXY)       ||
		   !_tcscmp(micro_exe.cmovet, MICRO_MOV_TV)       ||
		   !_tcscmp(micro_exe.cmovet, MICRO_ROT_TV)       ||
		   !_tcscmp(micro_exe.cmovet, MICRO_CTRL_OP)		 ||
		   !_tcscmp(micro_exe.cmovet, MICRO_MOVE_FAGR_MM)){
			//Non devo gestire variazioni di peso o di oggetti.//
		}
		else if(!_tcscmp(micro_exe.cmovet, MICRO_MOVE_FAGRL_MM) && (mmTDPos != -1)){
			//Se il comando era di apertura lascio un oggetto nella cella.//
			if(micro_exe.xyz_quo1 == 1){
				//Controllo sul mast quale oggetto sto lasciando.//
				if(mastSituation.obj[OBJT_N_HECA] != 0){
					retstat = InsertObject(&cellSituation, &mastSituation, mastSituation.o_id[OBJT_N_HECA], mastSituation.obj[OBJT_N_HECA], cellType);
					if(retstat != RT_NORMAL){
						_stprintf_s(ENM_LogMsg, _T("Error: cannot insert Hermetic cask in dest cell."));
						ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
						SetMiceStatus(micro_exe.index, MICE_FAILED);
						if(sendMsg)
							SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
						return (RT_FAILED);
					}
				}
				else if(mastSituation.obj[OBJT_N_FA] != 0){
					retstat = InsertObject(&cellSituation, &mastSituation, mastSituation.o_id[OBJT_N_FA], mastSituation.obj[OBJT_N_FA], cellType);
					if(retstat != RT_NORMAL){
						_stprintf_s(ENM_LogMsg, _T("Error: cannot insert FA in dest cell."));
						ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
						SetMiceStatus(micro_exe.index, MICE_FAILED);
						if(sendMsg)
							SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
						return (RT_FAILED);
					}
				}
				else if(mastSituation.obj[OBJT_N_CLUS_CAS] != 0){
					retstat = InsertObject(&cellSituation, &mastSituation, 0, mastSituation.obj[OBJT_N_CLUS_CAS], cellType);
					if(retstat != RT_NORMAL){
						_stprintf_s(ENM_LogMsg, _T("Error: cannot insert Cluster casing in dest cell."));
						ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
						SetMiceStatus(micro_exe.index, MICE_FAILED);
						if(sendMsg)
							SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
						return (RT_FAILED);
					}
				}
				
				else if(mastSituation.obj[OBJT_N_CLUS_FRM] != 0){
					retstat = InsertObject(&cellSituation, &mastSituation, mastSituation.o_id[OBJT_N_CLUS_FRM], mastSituation.obj[OBJT_N_CLUS_FRM], cellType);
					if(retstat != RT_NORMAL){
						_stprintf_s(ENM_LogMsg, _T("Error: cannot insert Cluster Frame in dest cell."));
						ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
						SetMiceStatus(micro_exe.index, MICE_FAILED);
						if(sendMsg)
							SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
						return (RT_FAILED);
					}
				}
				else if(mastSituation.obj[OBJT_N_COVER] != 0){
					retstat = GetMastAngle(&mastAngle);
					if((mastAngle >= (float)(0 - TOLL_MM_GR)) && (mastAngle <= (float)(0 + TOLL_MM_GR))){
						retstat = InsertObject(&cellSituation, &mastSituation, mastSituation.o_id[OBJT_N_COVER], mastSituation.obj[OBJT_N_COVER], cellType);
						if(retstat != RT_NORMAL){
							_stprintf_s(ENM_LogMsg, _T("Error: cannot insert Hermetic cask plug in dest cell."));
							ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
							SetMiceStatus(micro_exe.index, MICE_FAILED);
							if(sendMsg)
								SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
							return (RT_FAILED);
						}
					}
				}
				else if(mastSituation.obj[OBJT_N_FFDS_COV] != 0){
					retstat = GetMastAngle(&mastAngle);
					if((mastAngle >= (float)(0 - TOLL_MM_GR)) && (mastAngle <= (float)(0 + TOLL_MM_GR))){
						retstat = InsertObject(&cellSituation, &mastSituation, 0, mastSituation.obj[OBJT_N_FFDS_COV], cellType);
						if(retstat != RT_NORMAL){
							_stprintf_s(ENM_LogMsg, _T("Error: cannot insert FFDS cask plug in dest cell."));
							ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
							SetMiceStatus(micro_exe.index, MICE_FAILED);
							if(sendMsg)
								SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
							return (RT_FAILED);
						}
					}
				}
				
				retstat = UpdateCellSituation(micro_exe.Virt_X, micro_exe.Virt_Y, &cellSituation);
				if(retstat != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot update cell situation."));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
					SetMiceStatus(micro_exe.index, MICE_FAILED);
					if(sendMsg)
						SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
					return (RT_ERRINSR);
				}
				cellUpdated = true;
				retstat = UpdateMastSituation(&mastSituation);
				if(retstat != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot update cell situation."));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
					SetMiceStatus(micro_exe.index, MICE_FAILED);
					if(sendMsg)
						SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
					return (RT_ERRINSR);
				}
			}
			else if(micro_exe.xyz_quo1 == 0){
				//Chiusura latch//
				if((cellSituation.obj[OBJT_N_HECA] != 0) && cellSituation.obj[OBJT_N_COVER] != 0){
					retstat = RemoveObject(&cellSituation, &mastSituation, cellSituation.o_id[OBJT_N_HECA], cellSituation.obj[OBJT_N_HECA]);
					if(retstat != RT_NORMAL){
						_stprintf_s(ENM_LogMsg, _T("Error: cannot remove Hermetic cask from source cell."));
						ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
						SetMiceStatus(micro_exe.index, MICE_FAILED);
						if(sendMsg)
							SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
						return (RT_ERRREMO);
					}
				}
				else if((cellSituation.obj[OBJT_N_FA] != 0) && (cellSituation.obj[OBJT_N_COVER] == 0) && (cellSituation.obj[OBJT_N_FFDS_COV] == 0)){
					retstat = RemoveObject(&cellSituation, &mastSituation, cellSituation.o_id[OBJT_N_FA], cellSituation.obj[OBJT_N_FA]);
					if(retstat != RT_NORMAL){
						_stprintf_s(ENM_LogMsg, _T("Error: cannot remove FA from source cell."));
						ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
						SetMiceStatus(micro_exe.index, MICE_FAILED);
						if(sendMsg)
							SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
						return (RT_ERRREMO);
					}
				}
				else if((cellSituation.obj[OBJT_N_CLUS_CAS] != 0) && (cellSituation.obj[OBJT_N_FFDS_COV] == 0)){
					retstat = RemoveObject(&cellSituation, &mastSituation, 0, cellSituation.obj[OBJT_N_CLUS_CAS]);
					if(retstat != RT_NORMAL){
						_stprintf_s(ENM_LogMsg, _T("Error: cannot remove Cluster casing from source cell."));
						ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
						SetMiceStatus(micro_exe.index, MICE_FAILED);
						if(sendMsg)
							SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
						return (RT_ERRREMO);
					}
				}
				else if(cellSituation.obj[OBJT_N_COVER] != 0){
					retstat = RemoveObject(&cellSituation, &mastSituation, cellSituation.o_id[OBJT_N_COVER], cellSituation.obj[OBJT_N_COVER]);
					if(retstat != RT_NORMAL){
						_stprintf_s(ENM_LogMsg, _T("Error: cannot remove Hermetic Cask plug from source cell."));
						ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
						SetMiceStatus(micro_exe.index, MICE_FAILED);
						if(sendMsg)
							SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
						return (RT_ERRREMO);
					}
				}
				else if(cellSituation.obj[OBJT_N_FFDS_COV] != 0){
					retstat = RemoveObject(&cellSituation, &mastSituation, 0, cellSituation.obj[OBJT_N_FFDS_COV]);
					if(retstat != RT_NORMAL){
						_stprintf_s(ENM_LogMsg, _T("Error: cannot remove FFDS Cask plug from source cell."));
						ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
						SetMiceStatus(micro_exe.index, MICE_FAILED);
						if(sendMsg)
							SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
						return (RT_ERRREMO);
					}
				}
				else if(cellSituation.obj[OBJT_N_CLUS_FRM] != 0){
					retstat = RemoveObject(&cellSituation, &mastSituation, cellSituation.o_id[OBJT_N_CLUS_FRM], cellSituation.obj[OBJT_N_CLUS_FRM]);
					if(retstat != RT_NORMAL){
						_stprintf_s(ENM_LogMsg, _T("Error: cannot remove Cluster frame from source cell."));
						ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
						SetMiceStatus(micro_exe.index, MICE_FAILED);
						if(sendMsg)
							SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
						return (RT_ERRREMO);
					}
				}
				retstat = UpdateCellSituation(micro_exe.Virt_X, micro_exe.Virt_Y, &cellSituation);
				if(retstat != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot update cell situation."));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
					SetMiceStatus(micro_exe.index, MICE_FAILED);
					if(sendMsg)
						SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
					return (RT_ERRREMO);
				}
				cellUpdated = true;
				retstat = UpdateMastSituation(&mastSituation);
				if(retstat != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot update cell situation."));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
					SetMiceStatus(micro_exe.index, MICE_FAILED);
					if(sendMsg)
						SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
					return (RT_ERRREMO);
				}
			}
		}
		else if(!_tcscmp(micro_exe.cmovet, MICRO_MOVE_CLGR_MM) && (mmTDPos != -1)){
			if((micro_exe.Virt_X == svx) && (micro_exe.Virt_Y == svy) && !clusOnMast){
				retstat = RemoveObject(&cellSituation, &mastSituation, PhasObjIdx, PhasObjtIdx);
				if(retstat != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot insert object in dest cell."));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
					SetMiceStatus(micro_exe.index, MICE_FAILED);
					if(sendMsg)
						SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
					return (RT_ERRREMO);
				}
				retstat = UpdateCellSituation(svx, svy, &cellSituation);
				if(retstat != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot update cell situation."));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
					SetMiceStatus(micro_exe.index, MICE_FAILED);
					if(sendMsg)
						SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
					return (RT_ERRREMO);
				}
				cellUpdated = true;
				retstat = UpdateMastSituation(&mastSituation);
				if(retstat != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot update cell situation."));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
					SetMiceStatus(micro_exe.index, MICE_FAILED);
					if(sendMsg)
						SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
					return (RT_ERRREMO);
				}				
			}
			else if((micro_exe.Virt_X == dvx) && (micro_exe.Virt_Y == dvy) && clusOnMast){
				retstat = InsertObject(&cellSituation, &mastSituation, PhasObjIdx, PhasObjtIdx, cellType);
				if(retstat != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot insert object in dest cell."));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
					SetMiceStatus(micro_exe.index, MICE_FAILED);
					if(sendMsg)
						SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
					return (RT_ERRINSR);
				}
				retstat = UpdateCellSituation(micro_exe.Virt_X, micro_exe.Virt_Y, &cellSituation);
				if(retstat != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot update cell situation."));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
					SetMiceStatus(micro_exe.index, MICE_FAILED);
					if(sendMsg)
						SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
					return (RT_ERRINSR);
				}
				cellUpdated = true;
				retstat = UpdateMastSituation(&mastSituation);
				if(retstat != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot update cell situation."));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
					SetMiceStatus(micro_exe.index, MICE_FAILED);
					if(sendMsg)
						SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
					return (RT_ERRINSR);
				}		
			}
		}
		else if(!_tcscmp(micro_exe.cmovet, MICRO_ROT_MM) && (mmTDPos != -1)){
			if(micro_exe.xyz_quo1 == 45){
				if(cellType == CELL_HECA){
					cellSituation.obj[OBJT_N_HECA] = mastSituation.obj[OBJT_N_HECA];
					cellSituation.o_id[OBJT_N_HECA] = mastSituation.o_id[OBJT_N_HECA];
					mastSituation.obj[OBJT_N_HECA] = 0;
					mastSituation.o_id[OBJT_N_HECA] = 0;
					if(mastSituation.obj[OBJT_N_FA] != 0){
						cellSituation.obj[OBJT_N_FA] = mastSituation.obj[OBJT_N_FA];
						cellSituation.o_id[OBJT_N_FA] = mastSituation.o_id[OBJT_N_FA];
						mastSituation.obj[OBJT_N_FA] = 0;
						mastSituation.o_id[OBJT_N_FA] = 0;
					}
					if(mastSituation.obj[OBJT_N_CLUS] != 0){
						cellSituation.obj[OBJT_N_CLUS] = mastSituation.obj[OBJT_N_CLUS];
						cellSituation.o_id[OBJT_N_CLUS] = mastSituation.o_id[OBJT_N_CLUS];
						mastSituation.obj[OBJT_N_CLUS] = 0;
						mastSituation.o_id[OBJT_N_CLUS] = 0;
					}
				
					retstat = UpdateCellSituation(micro_exe.Virt_X, micro_exe.Virt_Y, &cellSituation);
					if(retstat != RT_NORMAL){
						_stprintf_s(ENM_LogMsg, _T("Error: cannot update cell situation."));
						ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
						SetMiceStatus(micro_exe.index, MICE_FAILED);
						if(sendMsg)
							SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
						return (RT_ERRINSR);
					}
					cellUpdated = true;
					retstat = UpdateMastSituation(&mastSituation);
					if(retstat != RT_NORMAL){
						_stprintf_s(ENM_LogMsg, _T("Error: cannot update cell situation."));
						ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
						SetMiceStatus(micro_exe.index, MICE_FAILED);
						if(sendMsg)
							SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
						return (RT_ERRINSR);
					}
				}
			}
			else if(micro_exe.xyz_quo1 == 0){
				if(cellType == CELL_HECA){
					mastSituation.obj[OBJT_N_HECA] = cellSituation.obj[OBJT_N_HECA];
					mastSituation.o_id[OBJT_N_HECA] = cellSituation.o_id[OBJT_N_HECA];
					cellSituation.obj[OBJT_N_HECA] = 0;
					cellSituation.o_id[OBJT_N_HECA] = 0;
					if(cellSituation.obj[OBJT_N_FA] != 0){
						mastSituation.obj[OBJT_N_FA] = cellSituation.obj[OBJT_N_FA];
						mastSituation.o_id[OBJT_N_FA] = cellSituation.o_id[OBJT_N_FA];
						cellSituation.obj[OBJT_N_FA] = 0;
						cellSituation.o_id[OBJT_N_FA] = 0;
					}
					if(cellSituation.obj[OBJT_N_CLUS] != 0){
						mastSituation.obj[OBJT_N_CLUS] = cellSituation.obj[OBJT_N_CLUS];
						mastSituation.o_id[OBJT_N_CLUS] = cellSituation.o_id[OBJT_N_CLUS];
						cellSituation.obj[OBJT_N_CLUS] = 0;
						cellSituation.o_id[OBJT_N_CLUS] = 0;
					}
				
					retstat = UpdateCellSituation(micro_exe.Virt_X, micro_exe.Virt_Y, &cellSituation);
					if(retstat != RT_NORMAL){
						_stprintf_s(ENM_LogMsg, _T("Error: cannot update cell situation."));
						ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
						SetMiceStatus(micro_exe.index, MICE_FAILED);
						if(sendMsg)
							SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
						return (RT_ERRINSR);
					}
					cellUpdated = true;
					retstat = UpdateMastSituation(&mastSituation);
					if(retstat != RT_NORMAL){
						_stprintf_s(ENM_LogMsg, _T("Error: cannot update cell situation."));
						ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
						SetMiceStatus(micro_exe.index, MICE_FAILED);
						if(sendMsg)
							SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
						return (RT_ERRINSR);
					}
				}
			}
		}
		
		//Scrivo la nuova situazione della cella sul file dei sinottici//
		if(cellUpdated){
			retstat = SetMimicCellSituation(micro_exe.mast, cellSituation);
			if(retstat != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot set mimics file cell situation."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
				SetMiceStatus(micro_exe.index, MICE_BREAK);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
				return (RT_FAILED);
			}
		}

		//Scrivo la nuova situazione della mast sul file dei sinottici//
		if(micro_exe.mast == MAIN_MAST){
			retstat = SetMimicMastSituation(micro_exe.mast);
			if(retstat != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot set mimics file mast situation."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
				SetMiceStatus(micro_exe.index, MICE_BREAK);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
				return (RT_FAILED);
			}
		}

		if(micro_exe.mast == MAIN_MAST){
			//Specifico gli oggetti presenti sul mast.//
			memcpy(&micro_exe.objt_mm, &mastSituation, sizeof(mastSituation));
			stat = SetObjectOnMast(micro_exe.mast, micro_exe.objt_mm);
			if(stat != R_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tags the objects on mast."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(61));
				SetMiceStatus(micro_exe.index, MICE_FAILED);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
				return(RT_FAILED);
			}

			clgrWeight = 0.0;
			if((mastSituation.obj[OBJT_N_CLUS] != 0) && (mastSituation.obj[OBJT_N_CLUS_CAS] != 0)){
				retstat = GetObjWeight(mastSituation.o_id[OBJT_N_CLUS], &objWeight);
				if(retstat != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: unable to retrieve object weight."));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
					SetMiceStatus(micro_exe.index, MICE_BREAK);
					if(sendMsg)
						SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
					return (RT_INVOBJ);
				}
				clgrWeight = objWeight;
			}
			weight = 0.0;
			objWeight = 0.0;
			for(j = 0; j < N_MAX_NONAM_OBJ; j++){
				if(mastSituation.obj[j] != 0){
					if(j < N_MAX_NAMED_OBJ){
						if(j == OBJT_N_CLUS){ 
							if((mastSituation.obj[OBJT_N_CLUS_CAS] == 0) && (j != OBJT_N_CLUS)){
								retstat = GetObjWeight(mastSituation.o_id[j], &objWeight);
								if(retstat != RT_NORMAL){
									_stprintf_s(ENM_LogMsg, _T("Error: unable to retrieve object weight."));
									ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
									SetMiceStatus(micro_exe.index, MICE_BREAK);
									if(sendMsg)
										SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
									return (RT_INVOBJ);
								}
							}
						}
						else{
							retstat = GetObjWeight(mastSituation.o_id[j], &objWeight);
							if(retstat != RT_NORMAL){
								_stprintf_s(ENM_LogMsg, _T("Error: unable to retrieve object weight."));
								ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
								SetMiceStatus(micro_exe.index, MICE_BREAK);
								if(sendMsg)
									SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
								return (RT_INVOBJ);
							}
						}
					}
					else{
						retstat = GetObjtWeight(mastSituation.obj[j], &objWeight);
						if(retstat != RT_NORMAL){
							_stprintf_s(ENM_LogMsg, _T("Error: unable to retrieve object type weight."));
							ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
							SetMiceStatus(micro_exe.index, MICE_BREAK);
							if(sendMsg)
								SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
							return (RT_INVOBJT);
						}
					}
					weight = weight + objWeight;
				}
			}
			switch(micro_exe.mast){
			case MAIN_MAST:
				retstat = VotedTagWrite(TWN_MM_EXP_WEIGHT, 0, weight, FLT_VALUE);
				if(retstat != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag MR_EXP"));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(61));
					SetMiceStatus(micro_exe.index, MICE_FAILED);
					if(sendMsg)
						SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
					return(RT_FAILED);
				}
				//Imposto il peso per il cluster gripper del MM.//
				retstat = VotedTagWrite(TWN_MM_CL_EXP_WEIGHT, 0, clgrWeight, FLT_VALUE);
				if(retstat != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag MR_CL_EXP"));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(61));
					SetMiceStatus(micro_exe.index, MICE_BREAK);
					if(sendMsg)
						SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
					return(RT_FAILED);
				}
				break;
			default:
				break;
			}
		}
		*/
		
		//Se il movimento � un controllo FALV//
		if((!_tcscmp(micro_exe.cmovet, MICRO_CTRL_OP)) && (micro_exe.xyz_quo1 == 0)){
			//Salvo i dati nell'apposito file DAFS//
			ZeroMemory(&falv, sizeof(t_falv));
			falv.virtX = micro_exe.Virt_X;
			falv.virtY = micro_exe.Virt_Y;
			retstat = GetCellSituation(micro_exe.Virt_X, micro_exe.Virt_Y, &falv.cellSituation);
			falv.qouteResult = micro_exe.res_1;
			GetCamp(&camp);
			falv.campSeqNum = camp.seqNum;
			falv.campYear = camp.year;
			GetApmsTimeEx(&falv.checkTime);
			retstat = InsertFALVRecord(falv);
			if(retstat != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot save data FALV buffer"));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(61));
				SetMiceStatus(micro_exe.index, MICE_FAILED);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
				return(RT_FAILED);
			}
		}

PROCEED:
		if(!_tcscmp(micro_exe.cmovet, MICRO_DMP_OP)){
			//Salvo i dati nell'apposito file DAFS//
			ZeroMemory(&dmp, sizeof(t_dmp));
			dmp.virtX = micro_exe.Virt_X;
			dmp.virtY = micro_exe.Virt_Y;
			dmp.qouteResult = micro_exe.res_1;
			GetCamp(&camp);
			dmp.campSeqNum = camp.seqNum;
			dmp.campYear = camp.year;
			GetApmsTimeEx(&dmp.checkTime);
			retstat = InsertDMPRecord(dmp);
			if(retstat != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot save data DMP buffer"));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(61));
				SetMiceStatus(micro_exe.index, MICE_FAILED);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
				return(RT_FAILED);
			}
		}
	
		//CONFIRM MOVEMENT EXECUTION//
		retstat = GetDynStopFlag(&stopFlag);
		micro_exe.exe = MICE_SUCCESS;
		retstat = SetMice(micro_exe);
		if(retstat != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on DAFS file F.MICE."));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(111));
			SetMiceStatus(micro_exe.index, MICE_FAILED);
			if(sendMsg)
				SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
			return (RT_FAILED);
		}
		else if(sendMsg)
			SendMessage(hWnd, WM_OP_FINISHED, NULL, NULL);
		//Metto in output l'ultima operazione eseguita.//
		*index = i;
		if (i <= next_move_a - 1){
			retstat = GetDynCurrentMode ( &current_mode );
			if ( retstat != RT_NORMAL ){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve dynamic current operating mode."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(112));
				SetMiceStatus(micro_exe.index, MICE_FAILED);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
				return (retstat);
			}
			//Se il modo � semiautomatico esco perch� si deve interrompere ad ogni mossa.//

			if(((current_mode == M_SEMIAUTO) && (micro_exe.stopFlag)) || (stopFlag != 0))
				break;
		}

		//Check if the phase has been finished //
		if ( i ==  next_move_a){
			/*
			stat = ResetObjectMoved();
			if(stat != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot reset objects moved."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(61));
				SetMiceStatus(micro_exe.index, MICE_FAILED);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
				return(RT_FAILED);
			}
			stat = FileRead ( &filePhas, current_phase, 1, &phases, sizeof(phases));
			if ( stat == R_NORMAL ){
				stat = GetApmsTimeEx(&phases.end_phse_time);
				phases.esito = PHAS_EXECUTED;
				stat = FileWrite ( &filePhas, current_phase, 1, &phases, sizeof(phases));
				if(stat != R_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot write on DAFS file F.PHAS."));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(113));
					SetMiceStatus(micro_exe.index, MICE_FAILED);
					if(sendMsg)
						SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
					return (RT_FAILED);
				}
			}
			else{
				_stprintf_s(ENM_LogMsg, _T("Error: cannot read from DAFS file F.PHAS."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(114));
				SetMiceStatus(micro_exe.index, MICE_FAILED);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
				return (RT_FAILED);
			}
			*/
			retstat = SetPhaseStatus(current_phase, PHAS_EXECUTED);
			if(retstat != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot set current phase EXECUTED status."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(115));
				SetMiceStatus(micro_exe.index, MICE_FAILED);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
				return (retstat);
			}
			retstat = SetPhaseEndTime(current_phase);
			if(retstat != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot set current phase END TIME."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(115));
				SetMiceStatus(micro_exe.index, MICE_FAILED);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
				return (retstat);
			}
			next_phase = current_phase + 1;
			current_phase = 0;
			retstat = SetDynCurrentPhase(current_phase);
			if(retstat != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot set current phase."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(115));
				SetMiceStatus(micro_exe.index, MICE_FAILED);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
				return (retstat);
			}
			retstat = SetDynNextPhase(next_phase);
			if(retstat != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot set next phase."));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(116));
				SetMiceStatus(micro_exe.index, MICE_FAILED);
				if(sendMsg)
					SendMessage(hWnd, WM_OP_FAILED, NULL, NULL);
				return (retstat);
			}
			SetSSTREntry(SSTR_TC_REC, _T("No Technological Cycles in progress"));
			SetSSTREntry(SSTR_MECH_REC, _T("No Technological Cycles in progress"));
			SetSSTREntry(SSTR_COORD_REC, _T("No Technological Cycles in progress"));
			SetSSTREntry(SSTR_OBJ_REC, _T("No Technological Cycles in progress"));
			SetSSTREntry(SSTR_TCSEQ_REC, _T("No Technological Cycles in progress"));
			SetPhaseSourceDestTags(0);
			if(sendMsg)
				SendMessage(hWnd, WM_OP_PH_FIN, NULL, NULL);
			if((micro_exe.mast == DMP_MAST) && (micro_exe.index != 0)){
				_stprintf_s(mbStr, _T("Please confirm start of Bridge and Trolley movement."));
				risp = MessageBox(hWnd, mbStr, _T("Mounting place Inspection"), MB_YESNO | MB_ICONINFORMATION);
				if(risp == IDNO){
					_stprintf_s(ENM_LogMsg, _T("Error: Operator didn't confirmed start for bridge/trolley movement in Inspection cycle."));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(106));
					SetMiceStatus(micro_exe.index, MICE_BREAK);
					if(sendMsg)
						SendMessage(hWnd, WM_OP_BREAK, NULL, NULL);
					return (RT_FAILED);
				}
			}
			return (RT_NORMAL);
			break;
		}

	}
	return (RT_NORMAL);
}

/*********************************************************************************************
**********************************************************************************************
**
** Function:		ExeMFPOutput
**
** Description:		Send to infi commands for the micro operation.
**
** Input:			micro_exe		- Micro command to execute.
**
** Return:			RETCOND			- R_NORMAL	-	Operation successful.
**									- R_XXXXXX	-	Otherwise.
** 
**********************************************************************************************
*********************************************************************************************/
RETCOND ExeMFPOutput(micro_cmd_exe *micro_exe, t_rpmb *rpmb, int sippReq){
	RETSTAT		retSt;
	RETCOND		stat;
	TAGIDX		tagPosIdx;
	TAGIDX		tagSp1Idx;
	TAGIDX		tagSp2Idx;
	TAGVALEX	tagPosVal;
	TAGVALEX	tagVal;
	float		tempSp;
	float		latchOpen;
	float		latchClose;
	int			sippWait;
	int			spCount;
	int			pcu;
	bool		sippEnabled;
	bool		sp1Ok;
	bool		sp2Ok;
	bool		synchro;
	bool		tvMount;
	BOOL		perm;	
	
	retSt = GetPcuNum(&pcu);
	if(retSt != RT_NORMAL)
		return(R_FAILED);

	/********************************************************************/
	/*			MOVIMENTI X,Y: BRIDGE, TROLLEY							*/
	/********************************************************************/
	
	//Movimento del bridge.//
	if(!(_tcscmp(micro_exe->cmovet, _T("MOVX")))){
		perm = IsPermEx(TWN_BRIDGE_MREQ);
		if(!perm){
			_stprintf_s(ENM_LogMsg, _T("Error: BRIDGE_MREQ is not permissive for set."));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
			return(R_FAILED);
		}
		//Resetto il movement request del TV Rotation per evitare i tre movimenti...//
		retSt = VotedTagWrite(TWN_TV_ROT_MREQ, 0, 0, DIG_VALUE);
		if(retSt != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag TV_MROT_REQ"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
			return(R_FAILED);
		}
		retSt = VotedTagWrite(TWN_BRIDGE_SP, 0, micro_exe->xyz_quo1, FLT_VALUE);
		if(retSt != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag BRIDGE_SP"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
			return(R_FAILED);
		}
		//Attivo la tag digitale corrispondente all'operazione.//
		retSt = VotedTagWrite(TWN_BRIDGE_MREQ, ACTIVATE_VAL, 0, DIG_VALUE);
		if(retSt != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag BRIDGE_MREQ"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(4));
			return(R_FAILED);
		}
		rpmb->movType = micro_exe->movet;
		rpmb->setPoint = micro_exe->xyz_quo1;
		stat = GetTagIdx(TWN_BRIDGE_POS, &tagPosIdx);
		stat = TagRead(&tagPosIdx, &tagPosVal);
		rpmb->startPos = tagPosVal.value.val_float;

		//Rilettura SP
		stat = GetTagIdx(TWN_BRIDGE_SP, &tagSp1Idx);
		if(stat != R_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot find tagIdx for BRIDGE_SP"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
			return(R_FAILED);
		}

		spCount = SP_READ_CYCLES;
		sp1Ok = false;
		while(spCount > 0){
			Sleep(SP_READ_WAIT);
			if(!sp1Ok){
				stat = TagRead(&tagSp1Idx, &tagVal);
				if(stat != R_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot read tag BRIDGE_SP"));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
					return(R_FAILED);
				}

				if((tagVal.value.val_float < (float)(micro_exe->xyz_quo1 - TOLL_MM)) || (tagVal.value.val_float > (float)(micro_exe->xyz_quo1 + TOLL_MM)))
					sp1Ok = false;
				else
					sp1Ok = true;
			}

			if(sp1Ok)
				break;

			spCount--;
		}

		if(!sp1Ok){
			_stprintf_s(ENM_LogMsg, _T("Error: bridge SP writing failed"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
			return(R_INVTAG);
		}

		Sleep(AFTER_SP_SLEEP);
	}
	
	//Movimento del trolley.//
	else if ( !(_tcscmp ( micro_exe->cmovet, _T("MOVY") ) ) ){
		perm = IsPermEx(TWN_TROLLEY_MREQ);
		if(!perm){
			_stprintf_s(ENM_LogMsg, _T("Error: TROLLEY_MREQ is not permissive for set."));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
			return(R_FAILED);
		}
		//Resetto il movement request del TV Rotation per evitare i tre movimenti...//
		retSt = VotedTagWrite(TWN_TV_ROT_MREQ, 0, 0, DIG_VALUE);
		if(retSt != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag TV_MROT_REQ"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
			return(R_FAILED);
		}
		retSt = VotedTagWrite(TWN_TROLLEY_SP, 0, micro_exe->xyz_quo1, FLT_VALUE);
		if(retSt != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag TROLLEY_SP"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(6));
			return(R_FAILED);
		}
		//Attivo la tag digitale corrispondente all'operazione.//
		retSt = VotedTagWrite(TWN_TROLLEY_MREQ, ACTIVATE_VAL, 0, DIG_VALUE);
		if(retSt != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag TROLLEY_MREQ"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
			return(R_FAILED);
		}
		rpmb->movType = micro_exe->movet;
		rpmb->setPoint = micro_exe->xyz_quo1;
		stat = GetTagIdx(TWN_TROLLEY_POS, &tagPosIdx);
		stat = TagRead(&tagPosIdx, &tagPosVal);
		rpmb->startPos = tagPosVal.value.val_float;

		//Rilettura SP
		stat = GetTagIdx(TWN_TROLLEY_SP, &tagSp1Idx);
		if(stat != R_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot find tagIdx for %s"), TWN_TROLLEY_SP);
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
			return(R_FAILED);
		}

		spCount = SP_READ_CYCLES;
		sp1Ok = false;
		while(spCount > 0){
			Sleep(SP_READ_WAIT);
			if(!sp1Ok){
				stat = TagRead(&tagSp1Idx, &tagVal);
				if(stat != R_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot read tag %s"), TWN_TROLLEY_SP);
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
					return(R_FAILED);
				}

				if((tagVal.value.val_float < (float)(micro_exe->xyz_quo1 - TOLL_MM)) || (tagVal.value.val_float > (float)(micro_exe->xyz_quo1 + TOLL_MM)))
					sp1Ok = false;
				else
					sp1Ok = true;
			}

			if(sp1Ok)
				break;

			spCount--;
		}

		if(!sp1Ok){
			_stprintf_s(ENM_LogMsg, _T("Error: trolley SP writing failed"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
			return(R_INVTAG);
		}

		Sleep (AFTER_SP_SLEEP);
	}
	
	//Movimento obliquo bridge-trolley.//
	else if ( !(_tcscmp ( micro_exe->cmovet, _T("MOVXY") ) ) ){
		perm = IsPermEx(TWN_BRIDGE_MREQ);
		if(!perm){
			_stprintf_s(ENM_LogMsg, _T("Error: BRIDGE_MREQ is not permissive for set."));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
			return(R_FAILED);
		}
		perm = IsPermEx(TWN_TROLLEY_MREQ);
		if(!perm){
			_stprintf_s(ENM_LogMsg, _T("Error: TROLLEY_MREQ is not permissive for set."));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
			return(R_FAILED);
		}
		//Resetto il movement request del TV Rotation per evitare i tre movimenti...//
		retSt = VotedTagWrite(TWN_TV_ROT_MREQ, 0, 0, DIG_VALUE);
		if(retSt != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag TV_MROT_REQ"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
			return(R_FAILED);
		}
		retSt = VotedTagWrite(TWN_BRIDGE_SP, 0, micro_exe->xyz_quo1, FLT_VALUE);
		if(retSt != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag BRIDGE_SP"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
			return(R_FAILED);
		}
		retSt = VotedTagWrite(TWN_TROLLEY_SP, 0, micro_exe->z_quo_2, FLT_VALUE);
		if(retSt != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag TROLLEY_SP"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(6));
			return(R_FAILED);
		}
		//Attivo le tag digitali corrispondenti all'operazione.//
		retSt = VotedTagWrite(TWN_BRIDGE_MREQ, ACTIVATE_VAL, 0, DIG_VALUE);
		if(retSt != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag BRIDGE_MREQ"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(4));
			return(R_FAILED);
		}
		retSt = VotedTagWrite(TWN_TROLLEY_MREQ, ACTIVATE_VAL, 0, DIG_VALUE);
		if(retSt != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag TROLLEY_MREQ"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
			return(R_FAILED);
		}
		rpmb->movType = micro_exe->movet;
		rpmb->setPoint = micro_exe->xyz_quo1;
		stat = GetTagIdx(TWN_BRIDGE_POS, &tagPosIdx);
		stat = TagRead(&tagPosIdx, &tagPosVal);
		rpmb->startPos = tagPosVal.value.val_float;
		rpmb->setPoint_2 = micro_exe->z_quo_2;
		stat = GetTagIdx(TWN_TROLLEY_POS, &tagPosIdx);
		stat = TagRead(&tagPosIdx, &tagPosVal);
		rpmb->startPos_2 = tagPosVal.value.val_float;

		//Rilettura SP
		stat = GetTagIdx(TWN_BRIDGE_SP, &tagSp1Idx);
		if(stat != R_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot find tagIdx for %s"), TWN_BRIDGE_SP);
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
			return(R_FAILED);
		}

		stat = GetTagIdx(TWN_TROLLEY_SP, &tagSp2Idx);
		if(stat != R_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot find tagIdx for %s"), TWN_TROLLEY_SP);
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
			return(R_FAILED);
		}

		spCount = SP_READ_CYCLES;
		sp1Ok = false;
		sp2Ok = false;
		while(spCount > 0){
			Sleep(SP_READ_WAIT);
			if(!sp1Ok){
				stat = TagRead(&tagSp1Idx, &tagVal);
				if(stat != R_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot read tag %s"), TWN_BRIDGE_SP);
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
					return(R_FAILED);
				}

				if((tagVal.value.val_float < (float)(micro_exe->xyz_quo1 - TOLL_MM)) || (tagVal.value.val_float > (float)(micro_exe->xyz_quo1 + TOLL_MM)))
					sp1Ok = false;
				else
					sp1Ok = true;
			}

			if(!sp2Ok){
				stat = TagRead(&tagSp2Idx, &tagVal);
				if(stat != R_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot read tag %s"), TWN_TROLLEY_SP);
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
					return(R_FAILED);
				}

				if((tagVal.value.val_float < (float)(micro_exe->z_quo_2 - TOLL_MM)) || (tagVal.value.val_float > (float)(micro_exe->z_quo_2 + TOLL_MM)))
					sp2Ok = false;
				else
					sp2Ok = true;
			}

			if(sp1Ok && sp2Ok)
				break;

			spCount--;
		}

		if(!sp1Ok || !sp2Ok){
			_stprintf_s(ENM_LogMsg, _T("Error: bridge, trolley SP writing failed"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
			return(R_INVTAG);
		}

		Sleep (AFTER_SP_SLEEP);
	}
	
	
	/********************************************************************/
	/*	  MOVIMENTI Z: MAIN MAST, TV_MAST (FA e CLUSTER).				*/
	/********************************************************************/

	//Movimento verticale dell'FA gripper del MM.//
	else if ( !(_tcscmp ( micro_exe->cmovet, _T("FAGR_MM") ) ) ){
		perm = IsPermEx(TWN_FAGR_MREQ);
		if(!perm){
			_stprintf_s(ENM_LogMsg, _T("Error: TWN_FAGR_MREQ is not permissive for set."));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
			return(R_FAILED);
		}
		//Imposto il set point che il mast deve raggiungere.//
		retSt = VotedTagWrite(TWN_FAGR_SP, 0, micro_exe->xyz_quo1, FLT_VALUE);
		if(retSt != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag I_M_ROD_SP"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(61));
			return(R_FAILED);
		}
		
		//retSt = GetDynCurrentPhase(&currPhas);
		//retSt = GetPhasMarkReq(currPhas, &markReq);
		stat = GetTagIdx(TWN_TV_MOUNT, &tagPosIdx);
		if(stat != R_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot find idx for tag TWN_TV_MOUNT"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(60));
			return(R_FAILED);
		}
		stat = TagRead(&tagPosIdx, &tagVal);
		if(stat != R_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot read tag TWN_TV_MOUNT"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(60));
			return(R_FAILED);
		}
		if(GtBit((unsigned short)(tagVal.value.val_di), 15) == 1)
			tvMount = true;
		else
			tvMount = false;

		stat = GetTagIdx(TWN_MM_TV_SYNCRO, &tagPosIdx);
		if(stat != R_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot find idx for tag TWN_MM_TV_SYNCRO"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(60));
			return(R_FAILED);
		}
		stat = TagRead(&tagPosIdx, &tagVal);
		if(stat != R_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot read tag TWN_MM_TV_SYNCRO"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(60));
			return(R_FAILED);
		}
		if(GtBit((unsigned short)(tagVal.value.val_di), 15) == 1)
			synchro = true;
		else
			synchro = false;

		
		if(tvMount && synchro){
			stat = GetTagIdx(TWN_TVM_POS, &tagPosIdx);
			if(stat != R_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot find idx for tag TWN_TVM_POS"));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(60));
				return(R_FAILED);
			}
			stat = TagRead(&tagPosIdx, &tagPosVal);
			if(stat != R_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot read tag TWN_TVM_POS"));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(60));
				return(R_FAILED);
			}
			if((tagPosVal.value.val_float < (float)(micro_exe->z_quo_2 - TOLL_MM)) || (tagPosVal.value.val_float > (float)(micro_exe->z_quo_2 +TOLL_MM))){
				//Imposto il set point per TVMAST//
				retSt = VotedTagWrite(TWN_TVM_SP, 0, micro_exe->z_quo_2, FLT_VALUE);
				if(retSt != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag TWN_TVM_SP"));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(61));
					return(R_FAILED);
				}
				retSt = VotedTagWrite(TWN_TVM_MREQ, ACTIVATE_VAL, 0, DIG_VALUE);
				if(retSt != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag TWN_TVM_MREQ"));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(31));
					return(R_FAILED);
				}
			}
		}
		retSt = VotedTagWrite(TWN_FAGR_MREQ, ACTIVATE_VAL, 0, DIG_VALUE);
		if(retSt != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag M_ROD_MREQ"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(31));
			return(R_FAILED);
		}
		rpmb->movType = micro_exe->movet;
		rpmb->setPoint = micro_exe->xyz_quo1;

		//Rilettura SP
		stat = GetTagIdx(TWN_FAGR_SP, &tagSp1Idx);
		if(stat != R_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot find tagIdx for TWN_FAGR_SP"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
			return(R_FAILED);
		}

		spCount = SP_READ_CYCLES;
		sp1Ok = false;
		while(spCount > 0){
			Sleep(SP_READ_WAIT);
			if(!sp1Ok){
				stat = TagRead(&tagSp1Idx, &tagVal);
				if(stat != R_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot read tag %s"), TWN_FAGR_SP);
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
					return(R_FAILED);
				}

				if((tagVal.value.val_float < (float)(micro_exe->xyz_quo1 - TOLL_MM)) || (tagVal.value.val_float > (float)(micro_exe->xyz_quo1 + TOLL_MM)))
					sp1Ok = false;
				else
					sp1Ok = true;
			}

			if(sp1Ok)
				break;

			spCount--;
		}

		if(!sp1Ok){
			_stprintf_s(ENM_LogMsg, _T("Error: main mast SP writing failed"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
			return(R_INVTAG);
		}

		Sleep (AFTER_SP_SLEEP);
	}

	//Movimento verticale del cluster gripper del MM.//
	else if(!_tcscmp ( micro_exe->cmovet, MICRO_MOVE_CLGR_MM)){
		perm = IsPermEx(TWN_CLGR_MREQ);
		if(!perm){
			_stprintf_s(ENM_LogMsg, _T("Error: TWN_CLGR_MREQ is not permissive for set."));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
			return(R_FAILED);
		}
		retSt = VotedTagWrite(TWN_CLGR_SP, 0, micro_exe->xyz_quo1, FLT_VALUE);
		if(retSt != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag MR_CL_SP"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(33));
			return(R_FAILED);
		}
		
		//Attivo la tag digitale corrispondente all'operazione.//
		retSt = VotedTagWrite(TWN_CLGR_MREQ, ACTIVATE_VAL, 0, DIG_VALUE);
		if(retSt != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag MR_CL_MREQ"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(35));
			return(R_FAILED);
		}

		rpmb->movType = micro_exe->movet;
		rpmb->setPoint = micro_exe->xyz_quo1;
		stat = GetTagIdx(TWN_CLGR_POS, &tagPosIdx);
		stat = TagRead(&tagPosIdx, &tagPosVal);
		rpmb->startPos = tagPosVal.value.val_float;

		//Rilettura SP
		stat = GetTagIdx(TWN_CLGR_SP, &tagSp1Idx);
		if(stat != R_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot find tagIdx for %s"), TWN_CLGR_SP);
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
			return(R_FAILED);
		}

		spCount = SP_READ_CYCLES;
		sp1Ok = false;
		while(spCount > 0){
			Sleep(SP_READ_WAIT);
			if(!sp1Ok){
				stat = TagRead(&tagSp1Idx, &tagVal);
				if(stat != R_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot read tag %s"), TWN_CLGR_SP);
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
					return(R_FAILED);
				}

				if((tagVal.value.val_float < (float)(micro_exe->xyz_quo1 - TOLL_MM)) || (tagVal.value.val_float > (float)(micro_exe->xyz_quo1 + TOLL_MM)))
					sp1Ok = false;
				else
					sp1Ok = true;
			}

			if(sp1Ok)
				break;

			spCount--;
		}

		if(!sp1Ok){
			_stprintf_s(ENM_LogMsg, _T("Error: main mast cluster SP writing failed"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
			return(R_INVTAG);
		}

		Sleep (AFTER_SP_SLEEP);
	}

	//Movimento verticale del TV mast.//
	else if ( !(_tcscmp ( micro_exe->cmovet, _T("MOV_TVM") ) ) ){
		perm = IsPermEx(TWN_TVM_MREQ);
		if(!perm){
			_stprintf_s(ENM_LogMsg, _T("Error: TWN_TVM_MREQ is not permissive for set."));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
			return(R_FAILED);
		}
		retSt = VotedTagWrite(TWN_TVM_SP, 0, micro_exe->xyz_quo1, FLT_VALUE);
		if(retSt != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag TV_ROD_SP"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(57));
			return(R_FAILED);
		}
		//Attivo la tag digitale corrispondente all'operazione.//
		retSt = VotedTagWrite(TWN_TVM_MREQ, ACTIVATE_VAL, 0, DIG_VALUE);
		if(retSt != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag TV_ROD_MREQ"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(59));
			return(R_FAILED);
		}
		rpmb->movType = micro_exe->movet;
		rpmb->setPoint = micro_exe->xyz_quo1;
		stat = GetTagIdx(TWN_TVM_POS, &tagPosIdx);
		stat = TagRead(&tagPosIdx, &tagPosVal);
		rpmb->startPos = tagPosVal.value.val_float;

		//Rilettura SP
		stat = GetTagIdx(TWN_TVM_SP, &tagSp1Idx);
		if(stat != R_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot find tagIdx for %s"), TWN_TVM_SP);
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
			return(R_FAILED);
		}

		spCount = SP_READ_CYCLES;
		sp1Ok = false;
		while(spCount > 0){
			Sleep(SP_READ_WAIT);
			if(!sp1Ok){
				stat = TagRead(&tagSp1Idx, &tagVal);
				if(stat != R_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot read tag %s"), TWN_TVM_SP);
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
					return(R_FAILED);
				}

				if((tagVal.value.val_float < (float)(micro_exe->xyz_quo1 - TOLL_MM)) || (tagVal.value.val_float > (float)(micro_exe->xyz_quo1 + TOLL_MM)))
					sp1Ok = false;
				else
					sp1Ok = true;
			}

			if(sp1Ok)
				break;

			spCount--;
		}

		if(!sp1Ok){
			_stprintf_s(ENM_LogMsg, _T("Error: tv mast SP writing failed"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
			return(R_INVTAG);
		}

		Sleep (AFTER_SP_SLEEP);
	}


	/********************************************************************/
	/*		    	ROTAZIONI: MAIN MAST, TV_MAST						*/
	/********************************************************************/

	//Rotazione del  MM.//
	else if ( !(_tcscmp ( micro_exe->cmovet, _T("ROT_MM") ) ) ){
		perm = IsPermEx(TWN_MM_ROT_MREQ);
		if(!perm){
			_stprintf_s(ENM_LogMsg, _T("Error: TWN_MM_ROT_MREQ is not permissive for set."));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
			return(R_FAILED);
		}
		retSt = VotedTagWrite(TWN_MM_ROT_SP, 0, micro_exe->xyz_quo1, FLT_VALUE);
		if(retSt != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag MR_ROT_SP"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(37));
			return(R_FAILED);
		}
		Sleep(MFP_INPUT_LATCH_WAIT);
		//Attivo la tag digitale corrispondente all'operazione.//
		retSt = VotedTagWrite(TWN_MM_ROT_MREQ, ACTIVATE_VAL, 0, DIG_VALUE);
		if(retSt != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag MR_ROT_MREQ"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(39));
			return(R_FAILED);
		}
		rpmb->movType = micro_exe->movet;
		rpmb->setPoint = micro_exe->xyz_quo1;
		stat = GetTagIdx(TWN_MM_ROT_POS, &tagPosIdx);
		stat = TagRead(&tagPosIdx, &tagPosVal);
		rpmb->startPos = tagPosVal.value.val_float;

		//Rilettura SP
		stat = GetTagIdx(TWN_MM_ROT_SP, &tagSp1Idx);
		if(stat != R_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot find tagIdx for %s"), TWN_MM_ROT_SP);
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
			return(R_FAILED);
		}

		spCount = SP_READ_CYCLES;
		sp1Ok = false;
		while(spCount > 0){
			Sleep(SP_READ_WAIT);
			if(!sp1Ok){
				stat = TagRead(&tagSp1Idx, &tagVal);
				if(stat != R_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot read tag %s"), TWN_MM_ROT_SP);
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
					return(R_FAILED);
				}

				if((tagVal.value.val_float < (float)(micro_exe->xyz_quo1 - TOLL_MM)) || (tagVal.value.val_float > (float)(micro_exe->xyz_quo1 + TOLL_MM)))
					sp1Ok = false;
				else
					sp1Ok = true;
			}

			if(sp1Ok)
				break;

			spCount--;
		}

		if(!sp1Ok){
			_stprintf_s(ENM_LogMsg, _T("Error: main mast rotation SP writing failed"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
			return(R_INVTAG);
		}

		Sleep (AFTER_SP_SLEEP);
	}

	
	//Rotazione del TV mast.//
	else if ( !(_tcscmp ( micro_exe->cmovet, _T("ROT_TVM") ) ) ){
		perm = IsPermEx(TWN_TV_ROT_MREQ);
		if(!perm){
			_stprintf_s(ENM_LogMsg, _T("Error: TWN_TV_ROT_MREQ is not permissive for set."));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
			return(R_FAILED);
		}
		retSt = VotedTagWrite(TWN_TV_ROT_SP, 0, micro_exe->xyz_quo1, FLT_VALUE);
		if(retSt != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag TV_ROD_R_SP"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(61));
			return(R_FAILED);
		}
		//Attivo la tag digitale corrispondente all'operazione.//
		retSt = VotedTagWrite(TWN_TV_ROT_MREQ, ACTIVATE_VAL, 0, DIG_VALUE);
		if(retSt != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag TV_ROT_MREQ"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(63));
			return(R_FAILED);
		}
		rpmb->movType = micro_exe->movet;
		rpmb->setPoint = micro_exe->xyz_quo1;
		stat = GetTagIdx(TWN_TV_ROT_POS, &tagPosIdx);
		stat = TagRead(&tagPosIdx, &tagPosVal);
		rpmb->startPos = tagPosVal.value.val_float;

		//Rilettura SP
		stat = GetTagIdx(TWN_TV_ROT_SP, &tagSp1Idx);
		if(stat != R_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot find tagIdx for %s"), TWN_TV_ROT_SP);
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
			return(R_FAILED);
		}

		spCount = SP_READ_CYCLES;
		sp1Ok = false;
		while(spCount > 0){
			Sleep(SP_READ_WAIT);
			if(!sp1Ok){
				stat = TagRead(&tagSp1Idx, &tagVal);
				if(stat != R_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot read tag %s"), TWN_TV_ROT_SP);
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
					return(R_FAILED);
				}

				if((tagVal.value.val_float < (float)(micro_exe->xyz_quo1 - TOLL_MM)) || (tagVal.value.val_float > (float)(micro_exe->xyz_quo1 + TOLL_MM)))
					sp1Ok = false;
				else
					sp1Ok = true;
			}

			if(sp1Ok)
				break;

			spCount--;
		}

		if(!sp1Ok){
			_stprintf_s(ENM_LogMsg, _T("Error: tv mast rotation SP writing failed"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(8));
			return(R_INVTAG);
		}

		Sleep (AFTER_SP_SLEEP);
	}

	
	/********************************************************************/
	/*		MOVIMENTO FA Gripper Latch(eseguito con Cluster gripper)	*/
	/********************************************************************/
	else if(!(_tcscmp ( micro_exe->cmovet, MICRO_MOVE_FAGRL_MM))){
		perm = IsPermEx(TWN_FAGRL_MREQ);
		if(!perm){
			_stprintf_s(ENM_LogMsg, _T("Error: TWN_FAGRL_MREQ is not permissive for set."));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
			return(R_FAILED);
		}
		stat = GetTagIdx(TWN_FAGR_POS, &tagPosIdx);
		if(stat != R_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot find idx for tag M_ROD_POS"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(60));
			return(R_FAILED);
		}
		stat = TagRead (&tagPosIdx, &tagPosVal);
		if(stat != R_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot read on tag M_ROD_POS"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(61));
			return(R_FAILED);
		}
		//retSt = GetMMFixSP(&latchOpen, &latchClose);
		if(micro_exe->xyz_quo1 == 1){
			
			retSt = GetInfiBlockVal(8322, 0, &latchOpen);
			if(retSt != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: canot retrieve infi90 block value (1,1,%d,3,8322)."), pcu);
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(33));
				//return(R_FAILED);
			}
			else{
				latchClose = (float)(OFFSET_FIX_OP);
			}
			
			tempSp = (float)(tagPosVal.value.val_float + latchOpen);
			retSt = VotedTagWrite(TWN_CLGR_SP, 0, tempSp, FLT_VALUE);
			if(retSt != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag MR_CL_SP"));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(33));
				return(R_FAILED);
			}
			retSt = VotedTagWrite(TWN_FAGRL_UNFIX_REQ, 1, 0, DIG_VALUE);
			if(retSt != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag TWN_FAGRL_UNFIX_REQ"));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(33));
				return(R_FAILED);
			}
		}
		else if(micro_exe->xyz_quo1 == 0){		
			retSt = GetInfiBlockVal(8321, 0, &latchClose);
			if(retSt != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: canot retrieve infi90 block value (1,1,%d,3,8321)."), pcu);
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(33));
				//return(R_FAILED);
			}
			else{
				latchClose = (float)(OFFSET_FIX_CL);
			}

			
			tempSp = (float)(tagPosVal.value.val_float + latchClose);
			retSt = VotedTagWrite(TWN_CLGR_SP, 0, tempSp, FLT_VALUE);
			if(retSt != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag MR_CL_SP"));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(33));
				return(R_FAILED);
			}
			retSt = VotedTagWrite(TWN_FAGRL_FIX_REQ, 1, 0, DIG_VALUE);
			if(retSt != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag TWN_FAGRL_FIX_REQ"));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(33));
				return(R_FAILED);
			}
		}
		else{
			_stprintf_s(ENM_LogMsg, _T("Error: unknown FA gripper latch operating code."));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(33));
			return(R_FAILED);
		}
		
		//Attivo la tag digitale corrispondente all'operazione.//
		retSt = VotedTagWrite(TWN_FAGRL_MREQ, ACTIVATE_VAL, 0, DIG_VALUE);
		if(retSt != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag MR_CL_MREQ"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(35));
			return(R_FAILED);
		}
		rpmb->movType = micro_exe->movet;
		rpmb->setPoint = micro_exe->xyz_quo1;
		stat = GetTagIdx(TWN_FAGRL_FIXED, &tagPosIdx);
		stat = TagRead(&tagPosIdx, &tagPosVal);
		if(GtBit((short)(tagPosVal.value.val_di), 15) == 1)
			rpmb->startPos = 1;
		else
			rpmb->startPos = 0;
		Sleep (AFTER_SP_SLEEP);
	}

	/********************************************************************/
	/*		   MOVIMENTO Device per il controllo installazione FA		*/
	/********************************************************************/
	//Movimento verticale del device di controllo degli FA.//
	else if ( !(_tcscmp ( micro_exe->cmovet, MICRO_CTRL_OP) ) ){
		//Attivo la tag digitale corrispondente all'operazione.//
		perm = IsPermEx(TWN_FALV_MREQ);
		if(!perm){
			_stprintf_s(ENM_LogMsg, _T("Error: TWN_FALV_MREQ is not permissive for set."));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
			return(R_FAILED);
		}

		retSt = VotedTagWrite(TWN_FALV_MREQ, ACTIVATE_VAL, 0, DIG_VALUE);
		if(retSt != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag FALVL_MREQ"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(67));
			return(R_FAILED);
		}

		if(micro_exe->xyz_quo1 == 0){
			retSt = VotedTagWrite(TWN_FALVL_UP_REQ, 0, 0, DIG_VALUE);
			if(retSt != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag TWN_FALVL_UP_REQ"));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(67));
				return(R_FAILED);
			}
			retSt = VotedTagWrite(TWN_FALVL_DOWN_REQ, ACTIVATE_VAL, 1, DIG_VALUE);
			if(retSt != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag TWN_FALVL_DOWN_REQ"));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(67));
				return(R_FAILED);
			}
		
		}else{
			retSt = VotedTagWrite(TWN_FALVL_UP_REQ, ACTIVATE_VAL, 1, DIG_VALUE);
			if(retSt != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag TWN_FALVL_UP_REQ"));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(67));
				return(R_FAILED);
			}
			retSt = VotedTagWrite(TWN_FALVL_DOWN_REQ, 0, 0, DIG_VALUE);
			if(retSt != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag TWN_FALVL_DOWN_REQ"));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(67));
				return(R_FAILED);
			}
		}

		rpmb->movType = micro_exe->movet;
		rpmb->setPoint = micro_exe->xyz_quo1;
		rpmb->startPos = (float)(0);
		Sleep (AFTER_SP_SLEEP);
	}

	/********************************************************************/
	/*		   MOVIMENTO Device per il controllo delle celle			*/
	/********************************************************************/

	/********************************************************************/
	/*		   MOVIMENTO Displacing device								*/
	/********************************************************************/
	else if(!(_tcscmp(micro_exe->cmovet, MICRO_DISP_MM))){
		perm = IsPermEx(TWN_DISPL_MREQ);
		if(!perm){
			_stprintf_s(ENM_LogMsg, _T("Error: TWN_DISPL_MREQ is not permissive for set."));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
			return(R_FAILED);
		}
		if(micro_exe->xyz_quo1 == 0){
			retSt = VotedTagWrite(TWN_DISPL_DOWN_REQ, ACTIVATE_VAL, 0, DIG_VALUE);
			if(retSt != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag TWN_DISPL_DOWN_REQ"));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(67));
				return(R_FAILED);
			}
		}
		else{
			retSt = VotedTagWrite(TWN_DISPL_UP_REQ, ACTIVATE_VAL, 0, DIG_VALUE);
			if(retSt != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag TWN_DISPL_UP_REQ"));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(67));
				return(R_FAILED);
			}
		}
		//Attivo la tag digitale corrispondente all'operazione.//
		retSt = VotedTagWrite(TWN_DISPL_MREQ, ACTIVATE_VAL, 0, DIG_VALUE);
		if(retSt != RT_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag TWN_DISPL_MREQ"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(67));
			return(R_FAILED);
		}
		rpmb->movType = micro_exe->movet;
		rpmb->setPoint = micro_exe->xyz_quo1;
		if(micro_exe->xyz_quo1 == 0)
			rpmb->startPos = (float)(1);
		else
			rpmb->startPos = (float)(0);
		Sleep (AFTER_SP_SLEEP);
	}

	/********************************************************************/
	/*		  ATTIVAZIONE DEL MOVIMENTO PIANIFICATO						*/
	/********************************************************************/
	
	if(sippReq != 0){
		sippEnabled = false;
		GetTagIdx(TWN_SIPP_ENABLED, &tagPosIdx);
		for(sippWait = 0; sippWait <= MFP_OUTPUT_SIPP_CYCLES; sippWait++){
			TagRead(&tagPosIdx, &tagPosVal);
			if(GtBit((short)(tagPosVal.value.val_float),  15) == 1){
				sippEnabled = true;
				break;
			}
			sippWait++;
			Sleep(MFP_OUTPUT_SIPP_WAIT);
		}
		if(!sippEnabled){
			_stprintf_s(ENM_LogMsg, _T("Error: Sipping control requested but not started."));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(93));
			return(R_FAILED);
		}	
	}

	Sleep (BEFORE_START_SLEEP);
	
	retSt = VotedTagWrite(TWN_START_MOV, ACTIVATE_VAL, 0, DIG_VALUE);
	if(retSt != RT_NORMAL){
		_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag START_MOV"));
		ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(93));
		return(R_FAILED);
	}

	GetApmsTimeEx(&rpmb->startTime);
	GetDynCurrentMode(&rpmb->opMode);
	GetCurrentUserIdx(1, &rpmb->opIdx);

	Sleep(AFTER_START_SLEEP);

	return (R_NORMAL);
}

/*********************************************************************************************
**********************************************************************************************
**
** Function:		ExeMFPInput
**
** Description:		Wait for MFP operation feddback after calling ExeMFPOutput.
**
** Input:			micro_exe		- Micro command to execute.
**
** Return:			RETCOND			- R_NORMAL	-	Operation successful.
**									- R_XXXXXX	-	Otherwise.
** 
**********************************************************************************************
*********************************************************************************************/
RETCOND ExeMFPInput(micro_cmd_exe *micro_exe, t_rpmb *rpmb){
	RETCOND			stat;
	TAGIDX			tagStartIdx;
	TAGIDX			tagidx_ok;
	TAGIDX			tagidx_ko;
	TAGVALEX		tagVal;
	TAGVALEX		tagval_ok; 
	TAGVALEX		tagval_ko ;
	int				i;
	int				esito;
	int				tripFlag;
	int				count;
	TCHAR			tripStr[TRIP_DESCR_LEN];
	
	//Sleep (MFP_INPUT_INITIAL_SLEEP);
	esito = 0;
	stat = GetTagIdx(TWN_START_MOV , &tagStartIdx);
	if(stat != R_NORMAL){
		_stprintf_s(ENM_LogMsg, _T("Error: cannot find idx of tag START_MOV"));
		ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(94));
		return(stat);
	}
	for(i = MFP_INPUT_START_CYCLES; i > 0; i-- ){	
		stat = TagRead (&tagStartIdx, &tagVal);    
		if(stat != R_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot read tag START_MOV"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(95));
			return(stat);
		}
		if (GtBit((short)tagVal.value.val_di, 15) == 1){
			esito = 1;
			break;
		}
		Sleep(MFP_INPUT_START_WAIT);
	}

	if(!esito){
		_stprintf_s(ENM_LogMsg, _T("Error: MFPInput reached timeout waiting start signal value = 1."));
		ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(200));	
		return (R_FAILED);
	}

	esito = 0;
	for(i = MFP_INPUT_WAIT_CYCLES; i > 0; i-- ){	
		stat = TagRead (&tagStartIdx, &tagVal);    
		if(stat != R_NORMAL){
			_stprintf_s(ENM_LogMsg, _T("Error: cannot read tag START_MOV"));
			ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(95));
			return(stat);
		}
		if (GtBit((short)tagVal.value.val_di, 15) == 0){
			esito = 1;
			break;
		}
		Sleep (MFP_INPUT_FINAL_WAIT);
	}

	Sleep(MFP_INPUT_BEFORE_LAST_OP_WAIT);

	/* Nuovo controllo di Fine movimento */
	if ( esito ){
		count = 0;
		for ( i = MFP_INPUT_LAST_WAIT; i > 0; i-- ){
			stat = GetTagIdx(TWN_LAST_OP_OK, &tagidx_ok);
			if(stat != R_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot find idx of tag LAST_OP_OK"));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(96));
				return(stat);
			}
			stat = TagRead (&tagidx_ok, &tagval_ok);
			if(stat != R_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot read tag LAST_OP_OK"));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(97));
				return(stat);
			}
			stat = GetTagIdx(TWN_LAST_OP_NOOK, &tagidx_ko);
			if(stat != R_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot find idx of tag LAST_OP_NOOK"));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(98));
				return(stat);
			}
			stat = TagRead (&tagidx_ko, &tagval_ko); 
			if(stat != R_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot read tag LAST_OP_NOOK"));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(99));
				return(stat);
			}

			/* Se RESULT_OK = 1 e RESULT_KO = 0 tutto bene */  
			if ((GtBit((short)tagval_ok.value.val_di, 15) == 1) && (GtBit((short)tagval_ko.value.val_di, 15) == 0) ){
				GetApmsTimeEx(&rpmb->endTime);
				rpmb->result = RPMB_OP_OK;
				SetRPMB(0, *rpmb);
				return (R_NORMAL);
			}

			/* Se RESULT_OK = 0 e RESULT_KO = 1 tutto male */  
			if ( (GtBit ( (short)tagval_ok.value.val_di, 15 ) == 0) &&
				(GtBit ( (short)tagval_ko.value.val_di, 15 ) == 1) ){
				GetApmsTimeEx(&rpmb->endTime);
				rpmb->result = RPMB_OP_NOOK;
				SetRPMB(0, *rpmb);
				GetTripInfo(&tripFlag, tripStr);
				if(tripFlag == TRIP_OFF)
					return (R_FAILED);
				else{
					_stprintf_s(ENM_LogMsg, _T("Error: MFPInput found values LAST_OP_OK = 0 e LAST_OP_NO_OK = 1"));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(99));	
					return (R_FAILED);
				}
			}

			/* Se RESULT_OK = 1 e RESULT_KO = 1 tutto male */  
			if ( (GtBit ( (short)tagval_ok.value.val_di, 15 ) == 1) &&
				(GtBit ( (short)tagval_ko.value.val_di, 15 ) == 1) ){
				GetApmsTimeEx(&rpmb->endTime);
				rpmb->result = RPMB_OP_NOOK;
				SetRPMB(0, *rpmb);
				GetTripInfo(&tripFlag, tripStr);
				if(tripFlag == TRIP_OFF)
					return (R_ABORTED);
				else{
					_stprintf_s(ENM_LogMsg, _T("Error: MFPInput found values LAST_OP_OK = 1 e LAST_OP_NO_OK = 1"));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(99));	
					return (R_FAILED);
				}
			}

			/* Se RESULT_OK = 0 e RESULT_KO = 0 aspetto un po' */  
			if ( (GtBit ( (short)tagval_ok.value.val_di, 15 ) == 0) &&
				(GtBit ( (short)tagval_ko.value.val_di, 15 ) == 0) ){
				GetTripInfo(&tripFlag, tripStr);
				if(tripFlag == TRIP_OFF){
					count++;
					if(count == MFP_INPUT_00_MAX)
						return (R_ABORTED);
					else
						Sleep (100);
				}
				else
					Sleep (100);
			}
		}
	}
	else{
		return (R_FAILED);
	}

	return (R_FAILED);
}

/*********************************************************************************************
**********************************************************************************************
**
** Function:		ENM_ActivateLog
**
** Description:		Activate the Log file.
**
** Return:			int				- 0 for success.
**									- -1 otherwise.
** 
**********************************************************************************************
*********************************************************************************************/
int ENM_ActivateLog(void){
	ENM_LogActive = true;
	return 0;
}

/*********************************************************************************************
**********************************************************************************************
**
** Function:		ENM_DeactivateLog
**
** Description:		Deactivate the Log file.
**
** Return:			int				- 0 for success.
**									- -1 otherwise.
** 
**********************************************************************************************
*********************************************************************************************/
int ENM_DeactivateLog(void){
	ENM_LogActive = false;
	return 0;
}

/*********************************************************************************************
**********************************************************************************************
**
** Function:		ENM_ActivateMsgBox
**
** Description:		Activate the message box error messages.
**
** Return:			int				- 0 for success.
**									- -1 otherwise.
** 
**********************************************************************************************
*********************************************************************************************/
int ENM_ActivateMsgBox(void){
	ENM_MsgBoxActive = true;
	return 0;
}

/*********************************************************************************************
**********************************************************************************************
**
** Function:		ENM_DeactivateMsgBox
**
** Description:		Deactivate the message box error messages.
**
** Return:			int				- 0 for success.
**									- -1 otherwise.
** 
**********************************************************************************************
*********************************************************************************************/
int ENM_DeactivateMsgBox(void){
	ENM_MsgBoxActive = false;
	return 0;
}
/*********************************************************************************************
**********************************************************************************************
**
** Function:		SetLogPath
**
** Description:		Cahge the Log file path.
**
** Input:			path			- New Log file path.
** Return:			int				- 0 for success.
**									- -1 otherwise.
** 
**********************************************************************************************
*********************************************************************************************/
int ENM_SetLogPath(TCHAR *path){
	_tcscpy_s(ENM_LogPath, path);
	return 0;
}

/*********************************************************************************************
**********************************************************************************************
**
** Function:		ENM_LogFileWrite
**
** Description:		Print a message in the application log file,
**
** Input:			cmd				- _T("ERR") - error, _T("WRN") - warning, _T("OK ") - success.
**					Comment			- Message description.
**
** Return:			int				- 1 for success.
**									- -1 otherwise.
** 
**********************************************************************************************
*********************************************************************************************/
int ENM_LogFileWrite(TCHAR cmd[4], TCHAR *Comment, int errNum){
	FILE		*LogFile;
	TCHAR		newLine = '\n';
	SYSTEMTIME	timeStamp;
	TCHAR		tempStr[256];
	TCHAR		timeStr[100];
	
	if(ENM_LogActive){
		
		errno_t err;
		err = _tfopen_s(&LogFile,ENM_LogPath, _T("a"));
		if (err != 0)
			return -1;
		
		//LogFile = _tfopen(ENM_LogPath, _T("a"));
		//if(LogFile == NULL)
		//	return -1;
		
		GetSystemTime(&timeStamp);
		_stprintf_s(timeStr, _T("[hh%2d  mm%2d  ss%2d,%3d (GMT)] [%2d-%2d-%4d]"), timeStamp.wHour, timeStamp.wMinute, timeStamp.wSecond, timeStamp.wMilliseconds, timeStamp.wDay, timeStamp.wMonth, timeStamp.wYear);
		if(_tcscmp(cmd, _T("ERR")) == 0)
			_ftprintf(LogFile,_T("%s   %s  %s Err.N� %d.%c"), timeStr, cmd, Comment, errNum,  newLine);
		else
			_ftprintf(LogFile,_T("%s   %s  %s%c"), timeStr, cmd, Comment, newLine);
		if(fclose(LogFile)!=0)
			return -1;
	}
		
	if((ENM_MsgBoxActive) && (_tcscmp(cmd, _T("ERR")) == 0)){
		_stprintf_s(tempStr, _T("Error n.%d, %s"), errNum, Comment);
		MessageBox(NULL, tempStr, _T("Error"), MB_ICONWARNING||MB_OK);
	}

	return 0;
}

/*********************************************************************************************
**********************************************************************************************
**
** Function:		SetObjectMoved
**
** Description:		Set a tag that represents the object type actually moved.
**
** Return:			RETCOND			- R_NORMAL for success.
**									- R_FAILED otherwise.
** 
**********************************************************************************************
*********************************************************************************************/
RETCOND SetObjectMoved(micro_cmd_exe *mice){
	/*
	RETSTAT			retSt;
	MAC_CMDNAME		macrName;
	OBJTNAME		objtName;
	OBJNAME			objName;
	GENIDX			objtIdx;
	GENIDX			objIdx;
	OBJTCELL		cellSituation;
	int				genTypeCode;
	short int		svx, svy, dvx, dvy;
	bool			clus_also, FA_also;

	clus_also = false;
	FA_also = false;
	
	retSt = GetPhaseMacroName(mice->phase, macrName);
	if(retSt != RT_NORMAL){
		_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve phase %d macro command name."), mice->phase);
		ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
		return(R_FAILED);
	}
	
	retSt = GetPhaseObjtName(mice->phase, objtName);
	if(retSt != RT_NORMAL){
		_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve phase %d object type name."), mice->phase);
		ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
		return(R_FAILED);
	}

	retSt = GetPhaseObjectName(mice->phase, objName);
	if(retSt != RT_NORMAL){
		_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve phase %d object name."), mice->phase);
		ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
		return(R_FAILED);
	}

	retSt = GetPhaseSourceVirtCoo(mice->phase, &svx, &svy);
	if(retSt != RT_NORMAL){
		_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve phase %d source virtual coordinates."), mice->phase);
		ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
		return(R_FAILED);
	}

	retSt = GetObjtIdx(objtName, &objtIdx);
	if(retSt != RT_NORMAL){
		_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve phase object type Idx."));
		ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
		return (R_FAILED);
	}
	
	retSt = GetObjIdx(objName, &objIdx);
	if(retSt != RT_NORMAL){
		_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve phase object Idx."));
		ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
		return (R_FAILED);
	}

	retSt = GetPhaseDestVirtCoo(mice->phase, &dvx, &dvy);
	if(retSt != RT_NORMAL){
		_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve phase %d dest. virtual coordinates."), mice->phase);
		ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
		return(R_FAILED);
	}

	retSt = GetObjtGenericTypeCode(objtIdx, &genTypeCode);
	if(retSt != RT_NORMAL){
		_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve generic type code."));
		ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
		return (R_FAILED);
	}

	retSt = GetCellSituation(svx, svy, &cellSituation);
	if(retSt != RT_NORMAL){
		_stprintf_s(ENM_LogMsg, _T("Error: cannot retrieve source cell situation."));
		ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(110));
		return (R_FAILED);
	}

	if((mice->Virt_X == svx) && (mice->Virt_Y == svy)){
		//Se sono al punto di partenza aggiungo gli oggetti da spostare al main mast.//
		
		retCnd = ResetObjectMoved();
		if(retCnd != R_NORMAL)
				return(retCnd);
		
		switch(genTypeCode){
		case OBJT_N_FA:
			//Controllo se nell'FA c'� un cluster//
			if(cellSituation.obj[OBJT_N_CLUS] != 0)
				clus_also = true;
			switch(mice->mast){
			case(MAIN_MAST):
				retSt = VotedTagWrite(TWN_FA_MOVE, ACTIVATE_VAL, 0, DIG_VALUE);
				if(retSt != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag FA_MM_MOVE"));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
					return(R_FAILED);
				}
				if(clus_also){
					//Sostituire le tag con quelle dei cluster quando saranno definite.//
					
				}
				break;
			}
			break;
		case OBJT_N_HECA:
			if(cellSituation.o_id[OBJT_N_FA] != 0)
				FA_also = true;
			//Le tag non esistono ancora per NFR e SFR//
			switch(mice->mast){
			case(MAIN_MAST):
				retSt = VotedTagWrite(TWN_HECA_MOVE, ACTIVATE_VAL, 0, DIG_VALUE);
				if(retSt != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag SC_MM_MOVE"));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
					return(R_FAILED);
				}
				//Imposto la Tag per il coperchio dell'HECA.//
				retSt = VotedTagWrite(TWN_HECA_PLUG_MOVE, ACTIVATE_VAL, 0, DIG_VALUE);
				if(retSt != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag SCPLUG_MM_MOVE"));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
					return(R_FAILED);
				}
				//Controllo se sposto anche un FA//
				if(FA_also){
					retSt = VotedTagWrite(TWN_FA_MOVE, ACTIVATE_VAL, 0, DIG_VALUE);
					if(retSt != RT_NORMAL){
						_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag FA_MM_MOVE"));
						ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
						return(R_FAILED);
					}
				}
				break;
			}
			break;
		case OBJT_N_COVER:
			retSt = VotedTagWrite(TWN_HECA_PLUG_MOVE, ACTIVATE_VAL, 0, DIG_VALUE);
				if(retSt != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag SCPLUG_MM_MOVE"));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
				return(R_FAILED);
			}
			break;
		case OBJT_N_CLUS_CAS:
			switch(mice->mast){
			case(MAIN_MAST):
				retSt = VotedTagWrite(TWN_CLUSCAS_MOVE, ACTIVATE_VAL, 0, DIG_VALUE);
				if(retSt != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag CLJ_MM_MOVE"));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
					return(R_FAILED);
				}
				break;
			}
			break;
		case OBJT_N_FFDS_COV:
			//Uso tag FFDS cask//
			retSt = VotedTagWrite(TWN_FFDS_PLUG_MOVE, ACTIVATE_VAL, 0, DIG_VALUE);
			if(retSt != RT_NORMAL){
				_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag FFDSCSK_MM_MOV"));
				ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
				return(R_FAILED);
			}
			break;
		case OBJT_N_CLUS:
			switch(mice->mast){
			case(MAIN_MAST):
				retSt = VotedTagWrite(TWN_CLUS_MOVE, ACTIVATE_VAL, 0, DIG_VALUE);
				if(retSt != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag CL_MM_MOVE"));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
					return(R_FAILED);
				}
				break;
			}
			break;
		case OBJT_N_CLUS_FRM:
			switch(mice->mast){
			case(MAIN_MAST):
				retSt = VotedTagWrite(TWN_CLUSFRM_MOVE, ACTIVATE_VAL, 0, DIG_VALUE);
				if(retSt != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag CL_MM_MOVE"));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
					return(R_FAILED);
				}
				break;
			}
			break;
		default:
			break;
		}
	}
	*/
	return(R_NORMAL);
}

/*********************************************************************************************
**********************************************************************************************
**
** Function:		SetObjectOnMast
**
** Description:		Set a tag that represents the object type actually on used mast.
**
** Return:			RETCOND			- R_NORMAL for success.
**									- R_FAILED otherwise.
** 
**********************************************************************************************
*********************************************************************************************/
RETCOND SetObjectOnMast(GENIDX mastType, OBJTMM mastSituation){
	RETSTAT			retSt;
	GENIDX			SFAIdx;
	int				i;
	int				objPresent;
	
	GetObjtIdx(_T("S_FA"), &SFAIdx);

	objPresent = 0;
	
	for(i = 0; i <= N_MAX_NONAM_OBJ; i++){
		if(mastSituation.obj[i] != 0)
			objPresent = 1;
		else
			objPresent = 0;
		switch(i){
		case OBJT_N_FA:
			switch(mastType){
			case MAIN_MAST:
				retSt = VotedTagWrite(TWN_FA_ON_MM, objPresent, 0, DIG_VALUE);
				if(retSt != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag FA_MM"));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
					return(R_FAILED);
				}
				/*
				if(mastSituation.o_id[OBJT_N_FA] == SFAIdx){
					retSt = VotedTagWrite(TWN_SPENT_FUEL, 1, 0, DIG_VALUE);
					if(retSt != RT_NORMAL){
						_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag SPENT_FUEL"));
						ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
						return(R_FAILED);
					}
				}
				else{
					retSt = VotedTagWrite(TWN_SPENT_FUEL, 0, 0, DIG_VALUE);
					if(retSt != RT_NORMAL){
						_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag SPENT_FUEL"));
						ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
						return(R_FAILED);
					}
				}
				*/
				break;
			}
			break;
		case OBJT_N_CLUS:
			if(mastSituation.o_id[OBJT_N_FA] == 0){
				switch(mastType){
				case MAIN_MAST:
					retSt = VotedTagWrite(TWN_CLUS_ON_MM, objPresent, 0, DIG_VALUE);
					if(retSt != RT_NORMAL){
						_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag CL_MM_CL"));
						ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
						return(R_FAILED);
					}
					break;
				}
			}
			break;
		case OBJT_N_HECA:
			switch(mastType){
			case MAIN_MAST:
				retSt = VotedTagWrite(TWN_HECA_ON_MM, objPresent, 0, DIG_VALUE);
				if(retSt != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag SC_MM"));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
					return(R_FAILED);
				}
				break;
			}
			break;
		case OBJT_N_COVER:
			switch(mastType){
			case MAIN_MAST:
				retSt = VotedTagWrite(TWN_HECA_PLUG_ON_MM, objPresent, 0, DIG_VALUE);
				if(retSt != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag SCPLUG_MM"));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
					return(R_FAILED);
				}
				break;
			}
			break;
		case OBJT_N_CLUS_CAS:
			switch(mastType){
			case MAIN_MAST:
				if(i == OBJT_N_CLUS_CAS){
					retSt = VotedTagWrite(TWN_CLUSCAS_ON_MM, objPresent, 0, DIG_VALUE);
					if(retSt != RT_NORMAL){
						_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag CLJ_MM"));
						ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
						return(R_FAILED);
					}
				}
				break;
			}
			break;
		case OBJT_N_CLUS_FRM:
			switch(mastType){
			case MAIN_MAST:
				if(i == OBJT_N_CLUS_FRM){
					retSt = VotedTagWrite(TWN_CLUSFRM_ON_MM, objPresent, 0, DIG_VALUE);
					if(retSt != RT_NORMAL){
						_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag CLFRM_MM"));
						ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
						return(R_FAILED);
					}
				}
				break;
			}
			break;
		case OBJT_N_FFDS_COV:
			switch(mastType){
			case MAIN_MAST:
				retSt = VotedTagWrite(TWN_FFDS_PLUG_ON_MM, objPresent, 0, DIG_VALUE);
				if(retSt != RT_NORMAL){
					_stprintf_s(ENM_LogMsg, _T("Error: cannot write on tag FFDSCSK_MM"));
					ENM_LogFileWrite(_T("ERR"), ENM_LogMsg, ENM_ERR_CODE(2));
					return(R_FAILED);
				}
				break;
			}
			break;
		}
	}

	return(R_NORMAL);
}

/*********************************************************************************************
**********************************************************************************************
**
** Function:		SetMicroOpResults
**
** Description:		Set the reached set points of the micro operation with specified index.
**
** Input			mice			- micro command structure to set result
**
** Return:			RETCOND			- R_NORMAL for success.
**									- R_FAILED otherwise.
** 
**********************************************************************************************
*********************************************************************************************/
RETCOND	SetMicroOpResults(micro_cmd_exe *mice){
	RETCOND			retCnd;
	TAGIDX			tagIdx;
	TAGVALEX		tagVal;
	FILEIDX			fileMice;
//	int				rec;
//	micro_cmd_exe	tempMice;

	fileMice.num = F_MICE;

	mice->res_1 = mice->xyz_quo1;
	mice->res_2 = mice->z_quo_2;

	if(!_tcscmp(mice->cmovet, MICRO_MOVEX)){
		retCnd = GetTagIdx(TWN_BRIDGE_POS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(retCnd);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(retCnd);
		mice->res_1 = tagVal.value.val_float;
	}
	else if(!_tcscmp(mice->cmovet, MICRO_MOVEY)){
		retCnd = GetTagIdx(TWN_TROLLEY_POS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(retCnd);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(retCnd);
		mice->res_1 = tagVal.value.val_float;

	}
	else if(!_tcscmp(mice->cmovet, MICRO_MOVEXY)){
		retCnd = GetTagIdx(TWN_BRIDGE_POS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(retCnd);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(retCnd);
		mice->res_1 = tagVal.value.val_float;

		retCnd = GetTagIdx(TWN_TROLLEY_POS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(retCnd);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(retCnd);
		mice->res_2 = tagVal.value.val_float;
	}
	else if(!_tcscmp(mice->cmovet, MICRO_MOVE_FAGR_MM)){
		retCnd = GetTagIdx(TWN_FAGR_POS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(retCnd);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(retCnd);
		mice->res_1 = tagVal.value.val_float;
	}
	else if(!_tcscmp(mice->cmovet, MICRO_MOVE_CLGR_MM)){
		retCnd = GetTagIdx(TWN_CLGR_POS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(retCnd);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(retCnd);
		mice->res_1 = tagVal.value.val_float;
	}
	else if(!_tcscmp(mice->cmovet, MICRO_MOVE_FAGRL_MM)){
		retCnd = GetTagIdx(TWN_FAGRL_UNFIXED, &tagIdx);
		if(retCnd != R_NORMAL)
			return(retCnd);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(retCnd);
		mice->res_1 = (float)tagVal.value.val_di;
	}
	else if(!_tcscmp(mice->cmovet, MICRO_ROT_MM)){
		retCnd = GetTagIdx(TWN_MM_ROT_POS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(retCnd);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(retCnd);
		mice->res_1 = tagVal.value.val_float;
	}
	else if(!_tcscmp(mice->cmovet, MICRO_MOV_TV)){
		retCnd = GetTagIdx(TWN_TVM_POS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(retCnd);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(retCnd);
		mice->res_1 = tagVal.value.val_float;
	}
	else if(!_tcscmp(mice->cmovet, MICRO_ROT_TV)){
		retCnd = GetTagIdx(TWN_TV_ROT_POS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(retCnd);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(retCnd);
		mice->res_1 = tagVal.value.val_float;
	}
	else if(!_tcscmp(mice->cmovet, MICRO_CTRL_OP)){
		retCnd = GetTagIdx(TWN_FALV_POS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(retCnd);
		Sleep(3000);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(retCnd);
		mice->res_1 = tagVal.value.val_float;
	}
	else if(!_tcscmp(mice->cmovet, MICRO_DMP_OP)){
		mice->res_1 = 0;
	}
	else if(!_tcscmp(mice->cmovet, MICRO_SIPP)){
		retCnd = GetTagIdx(TWN_SIPP_FA_DAMAGED, &tagIdx);
		if(retCnd != R_NORMAL)
			return(retCnd);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(retCnd);
		mice->res_1 = GtBit((short)(tagVal.value.val_di), 15);
	}
	else if(!_tcscmp(mice->cmovet, MICRO_DISP_MM)){
		mice->res_1 = 0;
	}
	return(R_NORMAL);
}

/*********************************************************************************************
**********************************************************************************************
**
** Function:		EraseNextMarking
**
** Description:		Erase next marking and MM operation from the sequence and compress the file
**
** Input			miceIndex		- micro command index to start
**
** Return:			RETCOND			- R_NORMAL for success.
**									- R_FAILED otherwise.
** 
**********************************************************************************************
*********************************************************************************************/
RETCOND EraseNextMarking(int miceIndex, int markRec){
	RETCOND				retCnd;
	micro_cmd_exe		tempMice;
	FILEIDX				fileIdx;
	int					rec;
	int					lastRec;

	fileIdx.num = F_MICE;

	if(markRec == 0)
		return(R_FAILED);

	retCnd = FileRead(&fileIdx, markRec - 1, 1, &tempMice, sizeof(micro_cmd_exe));
	if(retCnd != R_NORMAL)
		return(R_FAILED);
	if(_tcscmp(tempMice.cmovet, MICRO_MOVE_FAGR_MM))
		return(R_FAILED);

	for(rec = markRec + 1; rec <= N_MAX_MICENR; rec++){
		retCnd = FileRead(&fileIdx, rec, 1, &tempMice, sizeof(micro_cmd_exe));
		if(retCnd != R_NORMAL)
			return(R_FAILED);
	
		if(tempMice.index != 0){
			retCnd = FileWrite(&fileIdx, rec - 2, 1, &tempMice, sizeof(micro_cmd_exe));
			if(retCnd != R_NORMAL)
				return(R_FAILED);
		}
		else{
			lastRec = rec;
			break;
		}
	}

	for(rec = lastRec - 2; rec <= N_MAX_MICENR; rec++){
		ZeroMemory(&tempMice, sizeof(micro_cmd_exe));
		retCnd = FileWrite(&fileIdx, rec, 1, &tempMice, sizeof(micro_cmd_exe));
		if(retCnd != R_NORMAL)
			return(R_FAILED);
	}

	return(R_NORMAL);
}

/*********************************************************************************************
**********************************************************************************************
**
** Function:		GetNextMarkingOpNum
**
** Description:		Check if another marking is present in sequence
**
** Input			miceIndex		- micro command index to start
**
** Output			nextMark		- Next marking mice index
**
** Return:			RETCOND			- R_NORMAL for success.
**									- R_FAILED otherwise.
** 
**********************************************************************************************
*********************************************************************************************/
RETCOND GetNextMarkingOpNum(int miceIndex, int *nextMark){
	RETCOND				retCnd;
	micro_cmd_exe		tempMice;
	FILEIDX				fileIdx;
	int					rec;

	fileIdx.num = F_MICE;
	
	*nextMark = 0;
	for(rec = 1; rec <= N_MAX_MICENR; rec++){	
		retCnd = FileRead(&fileIdx, rec, 1, &tempMice, sizeof(micro_cmd_exe));
		if(retCnd != R_NORMAL)
			return(R_FAILED);
		if(tempMice.index > miceIndex){
			if(!_tcscmp(tempMice.cmovet, MICRO_TV_INSP)){
				*nextMark = tempMice.index;
				break;
			}
		}
		if(tempMice.index == 0)
			break;
	}
	
	if(*nextMark == 0)
		return(R_FAILED);
	else
		return(R_NORMAL);
}

RETSTAT ManageClusEngage(micro_cmd_exe micro_exe, HWND hWnd){
	RETSTAT			retSt;
	RETCOND			retCnd;
	TAGIDX			tiMMClusPos;
	TAGIDX			tiClOverload;
	TAGIDX			tiClNotEngaged;
	TAGVALEX		tagVal;
	GENIDX			zoneIdx;
	GENIDX			contIdx;
	ZONENAME		zoneName;
	ZONENAME		supZoneName;
	t_cell			cell;
	micro_cmd_exe	lastOp;
	OBJTCELL		objtCell;
	OBJTMM			objtMM;
	float			px;
	float			py;
	float			tdPos;
	float			clgrPos;
	float			clusTDZ3;
	float			clusTDZ1_TK13;
	float			clusTDZ1_LOAD;
	float			clusTDZ23;
	float			clusTDZ21;
	float			clusterMoveCheck;
	TCHAR			opMsg[512];


	retSt = GetInfiBlockVal(3483, 0, &clusTDZ21);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);

	retSt = GetInfiBlockVal(8722, 0, &clusTDZ23);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);

	retSt = GetInfiBlockVal(3484, 0, &clusTDZ3);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);

	retSt = GetInfiBlockVal(8618, 0, &clusTDZ1_LOAD);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);

	retSt = GetInfiBlockVal(8720, 0, &clusTDZ1_TK13);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);

	retSt = GetCMCParam(&clusterMoveCheck);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);

	retSt = GetCellVirtCoo(micro_exe.Virt_X, micro_exe.Virt_Y, &cell);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);

	memcpy(&objtCell, &cell.objt_cell, sizeof(OBJTCELL));
							
	retSt = GetMastSituation(&objtMM);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);

	retCnd = GetTagIdx(TWN_CLGR_POS, &tiMMClusPos);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = GetTagIdx(TWN_TRIP_MM_CL_OL, &tiClOverload);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = GetTagIdx(TWN_TRIP_MM_CL_NOT_EN, &tiClNotEngaged);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tiMMClusPos, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
						
	clgrPos = tagVal.value.val_float;

	retSt = GetMastPosInfiSC(MAIN_MAST, &px, &py, &zoneIdx);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);
						
	retSt = GetZoneIdxPhisCooSC(px, py, &zoneIdx);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);

	retSt = GetZoneName(zoneIdx, zoneName);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);

	retSt = GetZoneSuperZone(zoneName, supZoneName);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);

	if(!_tcscmp(supZoneName, ZONE_REACTOR))
		tdPos = clusTDZ3;
	else if(!_tcscmp(supZoneName, ZONE_IO)){
		GetDynCurrentCont(&contIdx);
		if(contIdx == Z1_CONT_TK13)
			tdPos = clusTDZ1_TK13;
		else if(contIdx == Z1_CONT_LOAD)
			tdPos = clusTDZ1_LOAD;							
	}else if(!_tcscmp(supZoneName, ZONE_FFDS))
		tdPos = clusTDZ23;
	else
		tdPos = clusTDZ21;

	if(clgrPos >= (float)(tdPos - clusterMoveCheck)){
		if((objtMM.obj[OBJT_N_CLUS] == 0) && (objtCell.obj[OBJT_N_CLUS] != 0) && (objtMM.obj[OBJT_N_CLUS_CAS] != 0)){
			retCnd = TagRead(&tiClOverload, &tagVal);
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
								
			if(tagVal.value.val_di == 1){
				//Cluster release failed//					
				retSt = RemoveObject(&objtCell, &objtMM, objtCell.o_id[OBJT_N_CLUS], objtCell.obj[OBJT_N_CLUS]);
				if(retSt != RT_NORMAL)
					return(RT_FAILED);
				
				retSt = UpdateCellSituation(micro_exe.Virt_X, micro_exe.Virt_Y, &objtCell);
				if(retSt != RT_NORMAL)
					return(RT_FAILED);

				retSt = UpdateMastSituation(&objtMM);
				if(retSt != RT_NORMAL)
					return(RT_FAILED);
							
				retSt = GetMice(micro_exe.index - 1, &lastOp);
				if(retSt == RT_NORMAL){
					if(!_tcscmp(lastOp.cmovet, MICRO_MOVE_CLGR_MM)){
						retSt = SetMiceStatus(lastOp.index, MICE_FAILED);
					}
				}

				SetObjectOnMast(MAIN_MAST, objtMM);
				retSt = SetWeightOnMast(objtMM);
				retSt = SetMimicMastSituation(MAIN_MAST);
				_stprintf_s(opMsg, _T("Cluster release in cell (%d,%d) failed.\nCluster has been inserted back on mast.\nTechnological cycle will restart from cluster downward movement."), micro_exe.Virt_X, micro_exe.Virt_Y);							
				::MessageBox(hWnd, opMsg, _T("Cluster movement"), MB_OK | MB_ICONWARNING);					
			}						
		}else if((objtMM.obj[OBJT_N_CLUS] != 0) && (objtCell.obj[OBJT_N_CLUS] == 0) && (objtMM.obj[OBJT_N_CLUS_CAS] != 0)){
			retCnd = TagRead(&tiClNotEngaged, &tagVal);
			if(retCnd != R_NORMAL)
				return(RT_FAILED);

			if(tagVal.value.val_di == 1){
				//Cluster engage failed//
				retSt = InsertObject(&objtCell, &objtMM, objtMM.o_id[OBJT_N_CLUS], objtMM.obj[OBJT_N_CLUS], cell.type);
				if(retSt != RT_NORMAL)
					return(RT_FAILED);

				retSt = UpdateCellSituation(micro_exe.Virt_X, micro_exe.Virt_Y, &objtCell);
				if(retSt != RT_NORMAL)
					return(RT_FAILED);
									
				retSt = UpdateMastSituation(&objtMM);
				if(retSt != RT_NORMAL)
					return(RT_FAILED);
						
				retSt = GetMice(micro_exe.index - 1, &lastOp);
				if(retSt == RT_NORMAL){
					if(!_tcscmp(lastOp.cmovet, MICRO_MOVE_CLGR_MM)){
						retSt = SetMiceStatus(lastOp.index, MICE_FAILED);
					}
				}

				SetObjectOnMast(MAIN_MAST, objtMM);
				retSt = SetWeightOnMast(objtMM);
				retSt = SetMimicMastSituation(MAIN_MAST);
				_stprintf_s(opMsg, _T("Cluster engagement from cell (%d,%d) failed.\nCluster has been inserted back in cell.\nTechnological cycle will restart from cluster downward movement."), micro_exe.Virt_X, micro_exe.Virt_Y);							
				::MessageBox(hWnd, opMsg, _T("Cluster movement"), MB_OK | MB_ICONWARNING);					
								
			}	
		}					
	}

	return(RT_NORMAL);
}	


RETSTAT GetCMCParam(float *param){
	LONG	res;
	LPDWORD	type;
	LPBYTE	data;
	LPDWORD size;
	HKEY	hKey;
    DWORD	dwBufLen = ENM_NAME_L;
	DWORD	active;
    
	size = 0;
	data = 0;
	type = 0;
	
	*param = 70.0;

	res = RegOpenKeyEx(	HKEY_LOCAL_MACHINE, 
						TEXT("SOFTWARE\\ABB\\Power Generation Portal\\Tianwan\\Twn_ObjectMover"),
						0,
						KEY_QUERY_VALUE,
						&hKey);
	if(res != ERROR_SUCCESS)
		return(RT_FAILED);	
			
	active = 0;
	dwBufLen = sizeof(active);
	res = RegQueryValueEx(	hKey,
							TEXT("ClusterCheckQuote"),
							NULL,
							NULL,
							(LPBYTE)&active,
							&dwBufLen);
	if(res == ERROR_SUCCESS){
		if(active <= 70)
			*param = (float)(70.0);
		else
			*param = (float)(active);
	}else
		*param = (float)(70.0);

	RegCloseKey(hKey);

	return(RT_NORMAL);
}